0

I've implemented drawing for component like in picture following way:

@Override
protected void onDraw(Canvas canvas) {
    int w = canvas.getWidth();
    int h = canvas.getHeight();

    if (mFinalBitmap == null) {
        mFinalBitmap = Bitmap.createBitmap(w, h,
                Bitmap.Config.ARGB_8888);
    }

    if (mTempCanvas == null) {
        mTempCanvas = new Canvas(mFinalBitmap);
    }

    if (mBackgroundBitmap == null) {
        mBackgroundBitmap = createBitmap(R.drawable.rounded_background,
                w, h);
    }

    if (mBackgroundImage == null) {
        mBackgroundImage = createBitmap(R.drawable.image_for_background, w, h);
    }

    mTempCanvas.drawBitmap(mBackgroundBitmap, 0, 0, null);
    mTempCanvas.drawBitmap(mBackgroundImage, 0, 0, mPaint);

    canvas.drawBitmap(mFinalBitmap, 0, 0, null);
}

private Bitmap createBitmap(int id, int width, int height) {

    Bitmap bitmap = BitmapFactory.decodeResource(getContext()
            .getResources(), id);

    return Bitmap.createScaledBitmap(bitmap, width, height, false);
}

Where mPaint has

mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

enter image description here

I'm wondering whether the code is good, or can be optimized for same result, it uses lot's of memory and is an potential trigger for OutOfMemoryError.

Thanks.

Niko
  • 8,093
  • 5
  • 49
  • 85
  • Have a look at [Masking(crop) image in frame](http://stackoverflow.com/q/12614542/593709) – Adil Soomro Oct 09 '13 at 05:44
  • Code is almost the same there, lot's of bitmap creating, temporary Canvas where to draw, using ARGB_888 for result bitmap making it heavy. Is this really the very best solution to do this? – Niko Oct 09 '13 at 05:49

1 Answers1

1

Following drawing can be achieved using BitmapShader with the image to be drawn, then I only need to create ALPHA_8 Bitmap to draw with Paint object using the shader. However shaders are pinned into window coordinates, so using this method inside scrolling components can cause some problems because the Matrix needs to be translated properly.

// Create bitmap shader
if (mShaderBitmap == null) {
    mShaderBitmap = use wanted bitmap here.
    BitmapShader shader = new BitmapShader(mShaderBitmap,
            TileMode.CLAMP, TileMode.CLAMP);
    mPaint.setShader(shader);
}

// Create alpha bitmap to draw with shader paint
if (mBitmapToDraw == null) {
    mBitmapToDraw = load the shape here with ALPHA_8 Config
}

canvas.drawBitmap(mBitmapToDraw, 0, 0, mPaint);
Niko
  • 8,093
  • 5
  • 49
  • 85
  • how to "translate Matrix properly"? I am using this method in custom drawable but it doesn't work on Android 4.0+, it's always pinned to the top left of the canvas (0,0) of the window, not my view! But I have tested on 2.3.3 and it works fine!?!? – d370urn3ur Apr 18 '14 at 13:48