绘制带圆角的ImageView时的效率问题

6

我有一个ImageView子类,用于绘制带圆角的图片。 该代码基于此答案,如下所示:

public class ImageViewRoundedCorners extends ImageView {
    ...
    @Override
    protected void onDraw(Canvas canvas) {
        Bitmap scaledBitmap = Bitmap.createBitmap(getMeasuredWidth(),
                                                  getMeasuredHeight(),
                                                  Bitmap.Config.ARGB_8888); 
        Canvas scaledCanvas = new Canvas(scaledBitmap);
        super.onDraw(scaledCanvas); 
        drawRoundedCornerBitmap(canvas, scaledBitmap, 
                                getMeasuredWidth(), getMeasuredHeight());

        scaledBitmap.recycle();
    }

    protected void drawRoundedCornerBitmap(Canvas outputCanvas, Bitmap input, int w, int h) {
        Bitmap output = Bitmap.createBitmap(w, h, Config.ARGB_8888);
        Canvas canvas = new Canvas(output);

        mPaint.reset();
        mPaint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);

        mPaint.setStyle(Paint.Style.FILL);
        canvas.drawPath(mClipPath, mPaint);

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

        outputCanvas.drawBitmap(output, 0, 0, null);
    }
}

使用这段代码可以绘制带有正确圆角的图像。为了避免在drawRoundedCornerBitmap的前两行中进行分配,我想直接绘制到outputCanvas上,该画布最初传递给onDraw。新实现如下所示:
protected void drawRoundedCornerBitmap(...) {
    mPaint.reset();
    mPaint.setAntiAlias(true);
    outputCanvas.drawARGB(0, 0, 0, 0);

    mPaint.setStyle(Paint.Style.FILL);
    outputCanvas.drawPath(mClipPath, mPaint);

    mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    outputCanvas.drawBitmap(input, 0, 0, mPaint);
}

由于某种原因,该代码似乎忽略了Porter-Duff模式,而只是使用普通(非圆角)角绘制图像。为什么会这样?在一个中间的Bitmap上绘制有什么作用可以让原始代码正常工作?


你找到解决方法了吗?我也在尝试同样的事情:( - Aamir Shah
1个回答

0

创建可绘制的 Romain Guy 已经替您完成了。我们不是链接工厂,但他的博客文章非常详细地解释了这一点,并提供了一种有效的方法。圆角矩形

真正的基本原则是创建一个BitmapShader并将其附加到一个Paint对象中,在自定义Drawable中绘制,这样你只需将该Drawable应用于ImageView即可。

使用可绘制的意思是图片只会在画布上绘制一次,也就是说,绘制图片只会进行一次,然后所有ImageView所做的就是缩放可绘制对象。


当你需要在imageView中缩放drawable时,这不是一件很麻烦的事吗? drawable被创建后会被拉伸或裁剪,这意味着你的角落看起来会很奇怪,不是吗? - secureboot
请记住,ImageView会将您传递给它的任何内容转换为Drawable,提供其大小,然后在Drawable上调用draw()。默认情况下,如果您有一个BitmapDrawable,它当然只会拉伸它,但是如果您传递了一个RoundedBitmapDrawable,它将根据该实现进行绘制。 - Chris.Jenkins

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接