Efficiency when drawing an ImageView with rounded corners

Viewed 1844

I have an ImageView subclass that I use to draw images with rounded corners. The code is based on this answer, and is as follows:

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);
    }
}

With this code, the image is drawn with properly rounded corners. To avoid the allocations on the first two lines of drawRoundedCornerBitmap, I want to draw directly to outputCanvas, which is the canvas originally passed to onDraw. The new implementation looks like this:

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);
}

For some reason, this code seems to ignore the Porter-Duff mode, and instead just draws the image with normal (non-rounded) corners. Why is this the case? What is it about drawing to an intermediate Bitmap that makes the original code work?

1 Answers
Related