Search code examples
androidmemorybitmapandroid-canvasscale

How to create canvas with large Bitmap, draw on it, and then scale to screen size to conserve memory?


Simply put, I have a Bitmap resource that is 1800 x 1800 pix due to the detail I need. I create a canvas from the Bitmap and then draw on it. After drawing is complete, It's attached to an ImageView. It works fine on devices with large Heaps but on small devices, it crashes. The Bitmap needs to be the same size for all devices when added to the canvas because the coordinates that I draw to are precise locations on the Bitmap.

Here is my code

initialBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.VeryLargeBitmap);  
mutableBitmap = initialBitmap.copy(Bitmap.Config.RGB_565, true);  
canvas = new Canvas(mutableBitmap);  

....draw stuff here  
canvas.drawLine(x, y, x2, y2, paint);   

ImageView.setImageBitmap(mutableBitmap);  
ImageView..setAdjustViewBounds(true);

I'm sure there is a better way. I have looked into OpenGL but have not tried it yet. It looks to complex for what I'm trying to accomplish.


Solution

  • BitmapFactory.Options o = new BitmapFactory.Options();
    o.inMutable = true;
    initialBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.VeryLargeBitmap, o);
    

    Doing this should remove the need to copy the bitmap to an immutable one. When you're done with it (saved to file or ready for a new one) do this:

    initialBitmap.recycle();
    initialBitmap = null;
    

    To remove any reference to it (NOTE: recycle may not be necessary but I like it "to make sure").

    EDIT:

    Special note is that creating a Bitmap is CPU intensive so it'd be best to decode it in a thread and start drawing when it's ready. You should never create a Bitmap in an onDraw or draw method.