IndoorAtlas SDK 2.0:使用Picasso和自定义ImageView [英] IndoorAtlas SDK 2.0: Using Picasso with custom ImageView

查看:250
本文介绍了IndoorAtlas SDK 2.0:使用Picasso和自定义ImageView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以......,我想使用 Picasso 图像加载器库和现有的自定义imageview类来加载,调整大小和旋转图像。问题是我没有成功,就好像我使用这个代码:Picasso.with(this).load(url).into(custom ImageView),它给了我一个错误并建议将参数强制转换为目标。将参数custom imageview转换为目标后,当我测试应用程序时,它给出了错误,说明在Logcat中自定义imageview无法转换为目标
解决这个问题之后,我使用了一段不同的代码,其中包含onBitmapLoaded方法,该方法对应于Picasso库的Target界面,我成功地能够加载,调整大小和旋转图像,但在我开发室内定位系统时,蓝点正在显示在视线之外。它被显示在视线/不正确之外的原因是因为自定义图像视图没有与毕加索一起用于加载和显示图像。以下是包含onBitmapLoaded方法的代码,其中我没有得到我想要的结果,它也不正确,因为片刻之后应用程序崩溃了这个错误java.lang.RuntimeException:Canvas:尝试使用循环位图android.graphics.Bitmap@1d21751f,它指的是自定义ImageView类中的代码行super.onDraw(canvas)

 私人IAFloorPlan mFloorPlan; 
private BlueDotView mImageView;
private Target mLoadTarget;

private void showFloorPlanImage(String filePath){
final String url = mFloorPlan.getUrl();

if(mLoadTarget == null){
mLoadTarget = new Target(){

@Override
public void onBitmapLoaded(Bitmap bitmap,Picasso。 LoadedFrom from){
Log.d(TAG,onBitmap加载尺寸:+ bitmap.getWidth()+x
+ bitmap.getHeight());
mImageView.setImage(ImageSource.bitmap(bitmap));
mImageView.setRadius(mFloorPlan.getMetersToPixels()* dotRadius);
//mImageView.setRotation(90);
// setupGroundOverlay(floorPlan,bitmap);
}

@Override
public void onPrepareLoad(Drawable placeHolderDrawable){
// N / A
}

@覆盖
public void onBitmapFailed(Drawable placeHolderDraweble){
Toast.makeText(AutomaticFloorPlanLoader.this,无法加载位图,
Toast.LENGTH_SHORT).show();
}
};
}

RequestCreator request = Picasso.with(this).load(url).rotate(90).resize(500,500);

final int bitmapWidth = mFloorPlan.getBitmapWidth();
final int bitmapHeight = mFloorPlan.getBitmapHeight();

if(bitmapHeight> MAX_DIMENSION){
request.resize(0,MAX_DIMENSION);
} else if(bitmapWidth> MAX_DIMENSION){
request.resize(MAX_DIMENSION,0);
}

request.into(mLoadTarget);
/ * DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager()。getDefaultDisplay()。getMetrics(displaymetrics);
int screenWidth = displaymetrics.widthPixels;
int screenHeight = displaymetrics.heightPixels;
LinearLayout.LayoutParams parms = new LinearLayout.LayoutParams(screenWidth,screenHeight);
mImageView.setLayoutParams(parms); * /
//Picasso.with(this).load(Uri.parse(mFloorPlan.getUrl())).into((Target)mImageView);
Log.w(TAG,showFloorPlanImage:+ filePath);
/ * mImageView.setRadius(mFloorPlan.getMetersToPixels()* dotRadius);
mImageView.setImage(ImageSource.uri(filePath));
mImageView.setRotation(90); * /
}

这是我的申请中上述代码的结果: http://i.imgur.com/kcSa2x1.png

 这里是自定义的ImageView类:

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.util.AttributeSet;

import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView;

公共类BlueDotView扩展SubsamplingScaleImageView {

//私有静态最终浮点数RATIO = 4f / 3f;
private float radius = 1.0f;
private PointF dotCenter = null;

public void setRadius(float radius){
this.radius = radius;
}

public void setDotCenter(PointF dotCenter){
this.dotCenter = dotCenter;
}

public BlueDotView(Context context){
this(context,null);
}

public BlueDotView(Context context,AttributeSet attr){
super(context,attr);
initialise();
}

private void initialise(){
setWillNotDraw(false);
setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_CENTER);
}

/ * public BlueDotView(Context context,AttributeSet attrs,int defStyle)
{
super(context,attrs,defStyle);
} * /

@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);

if(!isReady()){
return;
}

if(dotCenter!= null){
PointF vPoint = sourceToViewCoord(dotCenter);
// float scaledRadius = getScale()* radius;
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.BLUE);
canvas.drawCircle(vPoint.x,vPoint.y,10,paint);
}
}
}

我试过setLinearLayout,displayMetrics和onMeasure方法无法使用所有这些方法调整图像大小。



所以,总的来说我的问题是:我如何使用Picasso与自定义ImageView类/ imageView本身来加载,调整大小和旋转图像在这个特定的例子中正确显示蓝点?



如果你能帮助我解决这个问题,请提前多多谢谢。

解决方案

BlueDotView (此处: https://github.com/IndoorAtlas/ android-sdk-examples / blob / master / Basic / src / main / java / com / indooratlas / android / sdk / examples / imageview / BlueDotView.java )在IndoorAtlas的示例中扩展 SubsamplingScaleImageView 作者:Dave Morissey(这里: https://github.com/davemorrissey /子采样规模-图像视图)。 SubsamplingScaleImageView 不会扩展 android.widget.ImageView ,因此您无法直接将其用作加载目标: Picasso.with(this).load(url).into(mImageView)但你需要像你一样使用目标。 / p>

java.lang.RuntimeException:Canvas:尝试使用回收的位图android.graphics.Bitmap@1d21751f 这是因为 SubsamplingScaleImageView 与大多数图像加载库不兼容。在此处阅读更多内容: https:// github。 COM / davemorrissey /二次采样尺度图像视图/维基/ X.-使用与 - 毕加索。该链接还解释了将 SubsamplingScaleImageView 与Picasso混合的正确方法。快速破解是将位图的副本传递给图像视图:

  @Override 
public void onBitmapLoaded(Bitmap bitmap,Picasso.LoadedFrom from){
mImageView.setImage(ImageSource.bitmap(bitmap.copy(bitmap.getConfig(),true));
}

对于不经常更改但是浪费资源的小位图,这可能没问题大位图并且可能导致OOM异常。



看起来您正在将位图大小调整为500x500像素。如果您的原始平面图位图不是方形(?),那么您正在改变宽高比和正确定位蓝点将失败。要将位图的宽度设置为500px并仍然保持宽高比,请使用:调整大小(500,0)


So...., I want to use Picasso image loader library with an existing custom imageview class to load,resize,and rotate my image. The problem is I am unsuccessful with it as if I use this code: "Picasso.with(this).load(url).into(custom ImageView)",it gives me an error and suggests "cast parameter to target". After casting the parameter "custom imageview" to target, when I test the application it gives me error saying "custom imageview cannot be cast to target" in the Logcat. After this problem, I am using a different piece of code which contains "onBitmapLoaded" method which corresponds to the Picasso library's Target interface and I am successfully able to load,resize, and rotate the image,but as I am working on the development of an Indoor Positioning System, the blue dot is being displayed out of sight. The reason why it is being displayed out of sight/incorrectly is because the custom imageview is not being used with picasso to load and display the image. And here is the bit of code containing "onBitmapLoaded" method where I am not getting the result I want and it is also not correct, as after some moment the app crashes with this error "java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@1d21751f" and it refers to the line of code "super.onDraw(canvas)" in the custom ImageView class:

private IAFloorPlan mFloorPlan;
private BlueDotView mImageView;
private Target      mLoadTarget;

 private void showFloorPlanImage(String filePath) {
        final String url = mFloorPlan.getUrl();

        if (mLoadTarget == null) {
            mLoadTarget = new Target() {

                @Override
                public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                    Log.d(TAG, "onBitmap loaded with dimensions: " + bitmap.getWidth() + "x"
                            + bitmap.getHeight());
                    mImageView.setImage(ImageSource.bitmap(bitmap));
                    mImageView.setRadius(mFloorPlan.getMetersToPixels() * dotRadius);
                    //mImageView.setRotation(90);
                    //setupGroundOverlay(floorPlan, bitmap);
                }

                @Override
                public void onPrepareLoad(Drawable placeHolderDrawable) {
                    // N/A
                }

                @Override
                public void onBitmapFailed(Drawable placeHolderDraweble) {
                    Toast.makeText(AutomaticFloorPlanLoader.this, "Failed to load bitmap",
                            Toast.LENGTH_SHORT).show();
                }
            };
        }

        RequestCreator request = Picasso.with(this).load(url).rotate(90).resize(500,500);

        final int bitmapWidth = mFloorPlan.getBitmapWidth();
        final int bitmapHeight = mFloorPlan.getBitmapHeight();

        if (bitmapHeight > MAX_DIMENSION) {
            request.resize(0, MAX_DIMENSION);
        } else if (bitmapWidth > MAX_DIMENSION) {
            request.resize(MAX_DIMENSION, 0);
        }

        request.into(mLoadTarget);
        /*DisplayMetrics displaymetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
        int screenWidth = displaymetrics.widthPixels;
        int screenHeight = displaymetrics.heightPixels;
        LinearLayout.LayoutParams parms = new LinearLayout.LayoutParams(screenWidth,screenHeight);
        mImageView.setLayoutParams(parms);*/
        //Picasso.with(this).load(Uri.parse(mFloorPlan.getUrl())).into((Target) mImageView);
        Log.w(TAG, "showFloorPlanImage: " + filePath);
       /* mImageView.setRadius(mFloorPlan.getMetersToPixels() * dotRadius);
        mImageView.setImage(ImageSource.uri(filePath));
        mImageView.setRotation(90);*/
    }

Here is the result of the above code in my application: "http://i.imgur.com/kcSa2x1.png"

And here is the custom ImageView class:

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.util.AttributeSet;

import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView;

public class BlueDotView extends SubsamplingScaleImageView {

    //private static final float RATIO = 4f / 3f;
    private float radius = 1.0f;
    private PointF dotCenter = null;

    public void setRadius(float radius) {
        this.radius = radius;
    }

    public void setDotCenter(PointF dotCenter) {
        this.dotCenter = dotCenter;
    }

    public BlueDotView(Context context) {
        this(context, null);
    }

    public BlueDotView(Context context, AttributeSet attr) {
        super(context, attr);
        initialise();
    }

    private void initialise() {
        setWillNotDraw(false);
        setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_CENTER);
    }

    /*public BlueDotView(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
    }*/

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (!isReady()) {
            return;
        }

        if (dotCenter != null) {
            PointF vPoint = sourceToViewCoord(dotCenter);
            //float scaledRadius = getScale() * radius;
            Paint paint = new Paint();
            paint.setAntiAlias(true);
            paint.setStyle(Paint.Style.FILL);
            paint.setColor(Color.BLUE);
            canvas.drawCircle(vPoint.x, vPoint.y, 10, paint);
        }
    }
}

I have tried setLinearLayout,displayMetrics, and the onMeasure method and failed to resize the image with all of them.

So,overall my question is: how can I use Picasso with the custom ImageView class/the imageView itself to load,resize, and rotate the image and also displaying the blue dot correctly in this particular example?

Many thanks in advance if you can help me solve this problem.

解决方案

The BlueDotView (here: https://github.com/IndoorAtlas/android-sdk-examples/blob/master/Basic/src/main/java/com/indooratlas/android/sdk/examples/imageview/BlueDotView.java) in IndoorAtlas's example extends SubsamplingScaleImageView by Dave Morissey (here: https://github.com/davemorrissey/subsampling-scale-image-view). SubsamplingScaleImageView does not extend android.widget.ImageView and hence you cannot use it directly as load target: Picasso.with(this).load(url).into(mImageView) but you need to use Target just as you did.

What comes to java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@1d21751f this is because SubsamplingScaleImageView does not work out-of-the-box with most image loading libraries. Read more here: https://github.com/davemorrissey/subsampling-scale-image-view/wiki/X.-Using-with-Picasso. That link also explains the proper way of mixing SubsamplingScaleImageView with Picasso. The quick hack is to pass a copy of the Bitmap to image view:

@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
     mImageView.setImage(ImageSource.bitmap(bitmap.copy(bitmap.getConfig(), true));
}

This may be ok for small bitmaps that don't change often but is waste of resources for large bitmaps and can cause OOM exceptions.

It looks like your are resizing your bitmap to 500x500 pixels. If your original floor plan bitmap was not square (?) you are changing aspect ratio and positioning blue dot correctly will fail. To set e.g. width of your bitmap to 500px and still maintain aspect ratio, use: resize(500, 0).

这篇关于IndoorAtlas SDK 2.0:使用Picasso和自定义ImageView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆