当前位置: 首页 > 知识库问答 >
问题:

使用Ion循环ImageView

宇文迪
2023-03-14

我在用离子https://github.com/koush/ion

在我的应用程序中加载图像

我需要使用Transform将一些图像圈起来

但我在谷歌中遇到了一些崩溃,我想永远摆脱这个错误。

我怎么能摆脱它

这是我的课

public class CircleTransform implements Transform {

@Override
public Bitmap transform(Bitmap source) {
    int size = Math.min(source.getWidth(), source.getHeight());

    /* int x = (source.getWidth() - size) / 2 */;
    /* int y = (source.getHeight() - size) / 2 */;

    int x = (source.getWidth() - size);
    int y = (source.getHeight() - size);

    Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size);
    if (squaredBitmap != source) {
        source.recycle();
    }

    Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig());

    Canvas canvas = new Canvas(bitmap);
    Paint paint = new Paint();
    BitmapShader shader = new BitmapShader(squaredBitmap,
            BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
    paint.setShader(shader);
    paint.setAntiAlias(true);

    float r = size / 2f/* 2f */;
    canvas.drawCircle(r, r, r, paint);

    squaredBitmap.recycle();
    return bitmap;
}

@Override
public String key() {
    return "circle";
}
}

这就是我得到的Crash

  java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@41ff4570
 at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1084)
 at android.view.GLES20Canvas.drawBitmap(GLES20Canvas.java:844)
 at com.koushikdutta.ion.IonDrawable.draw(IonDrawable.java:673)
 at android.widget.ImageView.onDraw(ImageView.java:1019)
 at android.view.View.draw(View.java:14728)
 at android.view.View.getDisplayList(View.java:13588)
 at android.view.View.getDisplayList(View.java:13635)
 at android.view.View.draw(View.java:14430)
 at android.view.ViewGroup.drawChild(ViewGroup.java:3252)
 at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3070)
 at android.view.View.getDisplayList(View.java:13580)
 at android.view.View.getDisplayList(View.java:13635)
 at android.view.View.draw(View.java:14430)
 at android.view.ViewGroup.drawChild(ViewGroup.java:3252)
 at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3070)
 at android.view.View.draw(View.java:14739)
 at android.view.View.getDisplayList(View.java:13588)
 at android.view.View.getDisplayList(View.java:13635)
 at android.view.View.draw(View.java:14430)
 at android.view.ViewGroup.drawChild(ViewGroup.java:3252)
 at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3070)
 at android.view.View.getDisplayList(View.java:13580)
 at android.view.View.getDisplayList(View.java:13635)
 at android.view.View.draw(View.java:14430)
 at android.view.ViewGroup.drawChild(ViewGroup.java:3252)
 at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3070)
 at android.view.View.getDisplayList(View.java:13580)
 at android.view.View.getDisplayList(View.java:13635)
 at android.view.View.draw(View.java:14430)
 at android.view.ViewGroup.drawChild(ViewGroup.java:3252)
 at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3070)
 at android.view.View.getDisplayList(View.java:13580)
 at android.view.View.getDisplayList(View.java:13635)
 at android.view.View.draw(View.java:14430)
 at android.view.ViewGroup.drawChild(ViewGroup.java:3252)
 at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3070)
 at android.view.View.getDisplayList(View.java:13580)
 at android.view.View.getDisplayList(View.java:13635)
 at android.view.View.draw(View.java:14430)
 at android.view.ViewGroup.drawChild(ViewGroup.java:3252)
 at android.widget.ListView.drawChild(ListView.java:3387)
 at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3070)
 at android.widget.AbsListView.dispatchDraw(AbsListView.java:2554)
 at android.widget.ListView.dispatchDraw(ListView.java:3382)
 at android.view.View.draw(View.java:14739)
 at android.widget.AbsListView.draw(AbsListView.java:4093)
 at android.view.View.getDisplayList(View.java:13588)
 at android.view.View.getDisplayList(View.java:13635)
 at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3226)
 at android.view.View.getDisplayList(View.java:13509)
 at android.view.View.getDisplayList(View.java:13635)
 at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3226)
 at android.view.View.getDisplayList(View.java:13509)
 at android.view.View.getDisplayList(View.java:13635)
 at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3226)
 at android.view.View.getDisplayList(View.java:13509)
 at android.view.View.getDisplayList(View.java:13635)
 at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3226)
 at android.view.View.getDisplayList(View.java:13509)
 at android.view.View.getDisplayList(View.java:13635)
 at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3226)
 at android.view.View.getDisplayList(View.java:13509)
 at android.view.View.getDisplayList(View.java:13635)
 at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3226)
 at android.view.View.getDisplayList(View.java:13509)
 at android.view.View.getDisplayList(View.java:13635)
 at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3226)
 at android.view.View.getDisplayList(View.java:13509)
 at android.view.View.getDisplayList(View.java:13635)
 at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3226)
 at android.view.View.getDisplayList(View.java:13509)
 at android.view.View.getDisplayList(View.java:13635)
 at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3226)
 at android.view.View.getDisplayList(View.java:13509)
 at android.view.View.getDisplayList(View.java:13635)
 at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3226)
 at android.view.View.getDisplayList(View.java:13509)
 at android.view.View.getDisplayList(View.java:13635)
 at android.view.HardwareRenderer$GlRenderer.buildDisplayList(HardwareRenderer.java:1627)
 at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:1506)
 at android.view.ViewRootImpl.draw(ViewRootImpl.java:2722)
 at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2587)
 at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2210)
 at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1189)
 at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6223)
 at android.view.Choreographer$CallbackRecord.run(Choreographer.java:788)
 at android.view.Choreographer.doCallbacks(Choreographer.java:591)
 at android.view.Choreographer.doFrame(Choreographer.java:560)
 at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:774)
 at android.os.Handler.handleCallback(Handler.java:808)
 at android.os.Handler.dispatchMessage(Handler.java:103)
 at android.os.Looper.loop(Looper.java:193)
 at android.app.ActivityThread.main(ActivityThread.java:5292)
 at java.lang.reflect.Method.invokeNative(Native Method)
 at java.lang.reflect.Method.invoke(Method.java:515)
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
 at dalvik.system.NativeStart.main(Native Method)

共有3个答案

利稳
2023-03-14

以下几点对我很有效:

首先创建一个新的Imageview类,它扩展了默认的Imageview类,我称之为我的:ImageViewRound。下面是实现:

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.widget.ImageView;

public class ImageViewRounded extends ImageView {

    public ImageViewRounded(Context context) {
        super(context);
    }

    public ImageViewRounded(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ImageViewRounded(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        BitmapDrawable drawable = (BitmapDrawable) getDrawable();

        if (drawable == null) {
            return;
        }

        if (getWidth() == 0 || getHeight() == 0) {
            return;
        }

        Bitmap fullSizeBitmap = drawable.getBitmap();

        int scaledWidth = getMeasuredWidth();
        int scaledHeight = getMeasuredHeight();

        Bitmap mScaledBitmap;
        if (scaledWidth == fullSizeBitmap.getWidth()
                && scaledHeight == fullSizeBitmap.getHeight()) {
            mScaledBitmap = fullSizeBitmap;
        } else {
            mScaledBitmap = Bitmap.createScaledBitmap(fullSizeBitmap,
                    scaledWidth, scaledHeight, true /* filter */);
        }

        // Bitmap roundBitmap = getRoundedCornerBitmap(mScaledBitmap);

        // Bitmap roundBitmap = getRoundedCornerBitmap(getContext(),
        // mScaledBitmap, 10, scaledWidth, scaledHeight, false, false,
        // false, false);
        // canvas.drawBitmap(roundBitmap, 0, 0, null);

        Bitmap circleBitmap = getCircledBitmap(mScaledBitmap);

        canvas.drawBitmap(circleBitmap, 0, 0, null);

    }

    public Bitmap getRoundedCornerBitmap(Context context, Bitmap input,
            int pixels, int w, int h, boolean squareTL, boolean squareTR,
            boolean squareBL, boolean squareBR) {

        Bitmap output = Bitmap.createBitmap(w, h, Config.ARGB_8888);
        Canvas canvas = new Canvas(output);
        final float densityMultiplier = context.getResources()
                .getDisplayMetrics().density;

        final int color = 0xff424242;

        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, w, h);
        final RectF rectF = new RectF(rect);

        // make sure that our rounded corner is scaled appropriately
        final float roundPx = pixels * densityMultiplier;

        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

        // draw rectangles over the corners we want to be square
        if (squareTL) {
            canvas.drawRect(0, 0, w / 2, h / 2, paint);
        }
        if (squareTR) {
            canvas.drawRect(w / 2, 0, w, h / 2, paint);
        }
        if (squareBL) {
            canvas.drawRect(0, h / 2, w / 2, h, paint);
        }
        if (squareBR) {
            canvas.drawRect(w / 2, h / 2, w, h, paint);
        }

        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(input, 0, 0, paint);

        return output;
    }

    Bitmap getCircledBitmap(Bitmap bitmap) {

        Bitmap result = Bitmap.createBitmap(bitmap.getWidth(),
                bitmap.getHeight(), Config.ARGB_8888);






        Canvas canvas = new Canvas(result);

        int color = Color.BLUE;
        Paint paint = new Paint();
        Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());

        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
//        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
        canvas.drawCircle(bitmap.getWidth()/2, bitmap.getHeight()/2, bitmap.getHeight()/2, paint);

        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);



        return result;
    }

}

在您的布局中,将您的图像视图替换为新的ImageViewRound,如下所示:

<com.sampleproject.ImageViewRounded
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:id="@+id/myImage"
        android:src="@drawable/no_photo_icon"
        android:layout_marginRight="2dp"/>

最后,在我的示例中,在加载图像的地方,即我的arrayadapter的getview方法,我执行以下操作:

ImageView myImage=findViewById(R.id.myImage);
    Ion.with(context)
                    .load(your image url here)
                    .withBitmap().asBitmap()
                    .setCallback(new FutureCallback<Bitmap>() {
                        @Override
                        public void onCompleted(Exception e, Bitmap result) {
                            myImage.setImageBitmap(result);
                        }
                    });

查尔,你完了!

向实
2023-03-14

也许你不想使用另一个库。这是我的解决方案:

Ion.with(imageview)
            .error(R.drawable.img)
            .placeholder(R.drawable.img)
            .transform(new Transform() {
                @Override
                public Bitmap transform(Bitmap b) {
                    return ImageUtil.createCircleBitmap(b);
                }

                @Override
                public String key() {
                    return null;
                }
            })
            .load(url);

在ImageUtil中:

public static Bitmap createCircleBitmap(Bitmap bitmap){
    //设置一个与位图同样大小的新位图
    Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(),
            Bitmap.Config.ARGB_8888);

    //设置一个图片大小的矩形
    final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
    Canvas canvas = new Canvas(output);
    final Paint paint = new Paint();
    paint.setAntiAlias(true);
    int halfWidth = bitmap.getWidth()/2;
    int halfHeight = bitmap.getHeight()/2;
    canvas.drawCircle(halfWidth, halfHeight, Math.max(halfWidth, halfHeight), paint);
    //设置为取两层图像交集部门,只显示上层图像
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    //画图像
    canvas.drawBitmap(bitmap, rect, rect, paint);
    return output;
}

这对我来说很有效。但我不知道关键方法在离子转换中意味着什么。有人能告诉我吗?

国高杰
2023-03-14

我刚刚添加了对RoundedImageView的支持。

https://github.com/koush/ion/blob/master/ion-sample/src/com/koushikdutta/ion/sample/RoundedImageViewSample.java

 类似资料:
  • ION

    ION 是一个公共的、无权限的去中心化标识符(DID)网络,它在比特币之上实现 Sidetree 协议(作为“第 2 层”覆盖)以大规模支持 DID / DPKI。 关键点: ION 是公共的,没有许可 - 系统是去中心化的,没有公司、组织或团体拥有/控制系统中的标识符和 PKI 条目,没有人决定谁可以参与。 ION 不引入新的代币/硬币 - 比特币是 ION 网络链路方面运营中唯一的价值单位。

  • 如何通过XML实现这一点:使用特定的src创建,并使其带有边框?

  • 问题内容: 我也在学习Java和android。我们可以在while循环中执行的几乎所有事情都可以在while循环中执行。 我发现一个简单的条件,使用while循环比for循环更好 如果我必须在程序中使用counter的值,那么我认为while循环要比for循环好 使用while循环 在这种情况下,我发现while循环要比for循环好,因为如果要在for循环中实现相同的效果,则必须将counter

  • 为什么我们要在while循环后面加一个分号()? 我以以下代码为例: 那么在这里做什么呢?

  • Cesium ion是一个提供瓦片图和3D地理空间数据的平台,Cesium ion支持把数据添加到用户自己的CesiumJS应用中。下面我们将使用Sentinal-2二维贴图和Cesium世界地形,二者都需要ion的支持。 备注 在我们使用Cesium的过程中,如果没有申请ion,同时没有自己的数据源用的cesium提供的数据源,viewer的底部常常会提示一行小的英文字母。大意就是需要申请acc

  • IonPhaser Web Component built with Stencil.js to integrate Phaser with any other framework. Inspired by the old IonPhaser directive Demo Do you want to see this web component in action? Visit https://