AndroidDev
AndroidDev

Reputation: 5575

Performance in merging several PNG files during runtime and displaying the resulting Bitmap

I'm trying to merge several png files during runtime and displaying the resulting Bitmap. But the performance seems bad (it takes around half a second to display the image). Are there are alternate methods to improve the performance?

All the images are Full Screen PNG images where some images have different transparent areas so the order of merging is important.

I have tried pre-loading the resources by decodeResource but I'm running out of memory after loading at around 40 PNG files into Bitmap files. Even though the PNG file is just 10KB when I decode it into a Bitmap its size is in couple of MB. I have hundreds of PNG files so pre-loading the resources is not possible and crashing the app due to memory exhaustion.

Sample code:

Bitmap background = decodeResource(context.getResources(), R.drawable.background);
Bitmap bmp1 = decodeResource(context.getResources(), R.drawable.png1);
Bitmap bmp2 = decodeResource(context.getResources(), R.drawable.png2);
Bitmap bmp3 = decodeResource(context.getResources(), R.drawable.png3);
Bitmap bmp4 = decodeResource(context.getResources(), R.drawable.png4);
Bitmap bmp5 = decodeResource(context.getResources(), R.drawable.png5);
Bitmap bmp6 = decodeResource(context.getResources(), R.drawable.png6);
Bitmap bmp7 = decodeResource(context.getResources(), R.drawable.png7);
Bitmap bmp8 = decodeResource(context.getResources(), R.drawable.png8);
Bitmap bmp9 = decodeResource(context.getResources(), R.drawable.png9);
Bitmap bmp10 = decodeResource(context.getResources(), R.drawable.png10);
Bitmap bmp11 = decodeResource(context.getResources(), R.drawable.png11);
Bitmap bmp12 = decodeResource(context.getResources(), R.drawable.png12);

Bitmap bmOverlay = Bitmap.createBitmap(background.getWidth(), background.getHeight(), background.getConfig());
canvas = new Canvas(bmOverlay);     
canvas.drawBitmap(background, new Matrix(), null);
canvas.drawBitmap(bmp1, 0, 0, null);
canvas.drawBitmap(bmp2, 0, 0, null);
canvas.drawBitmap(bmp3, 0, 0, null);
canvas.drawBitmap(bmp4, 0, 0, null);
canvas.drawBitmap(bmp5, 0, 0, null);
canvas.drawBitmap(bmp6, 0, 0, null);
canvas.drawBitmap(bmp7, 0, 0, null);
canvas.drawBitmap(bmp8, 0, 0, null);
canvas.drawBitmap(bmp9, 0, 0, null);
canvas.drawBitmap(bmp10, 0, 0, null);
canvas.drawBitmap(bmp11, 0, 0, null);
canvas.drawBitmap(bmp12, 0, 0, null);

Drawable drawable =new BitmapDrawable(context.getResources(),bmOverlay);
ImageView image.setImageDrawable(drawable); 

Any other clever techniques that I can use to solve this problem?

Upvotes: 1

Views: 121

Answers (2)

greenapps
greenapps

Reputation: 11224

Do not create so many bitmaps at once from resource. On!y one. Then draw it. And recycle. Then take the next from resource, draw and recycle.

You should of course make a loop for it.

The file size of your png does not say all. Its the resolution of the image which determines the amount of memory needed for the bitmap.

Upvotes: -1

Mohammed Atif
Mohammed Atif

Reputation: 4523

First things first, pngs and jpegs are compressed format of image and hence they are smaller in size but bitmaps, as name suggests, are mapping of each bit of the image and its size depends on the actual resolution of the image and hence a 10kb jpeg can turn into 10mb bitmap.

Now the solution part,
As you mentioned that your pngs have transparency and order of merging is important, you can make a method something like

public static Bitmap mergePng(Bitmap baseBitmap, Bitmap newBitmap){
    Bitmap targetBitmap; //use target bitmap to store the result of merging
    //your login to merge the newBitmap on top of base bitmap
    newBitmap.recycle;
    baseBitmap.recycle;
    return targetBitmap;
}

if you dont want this method to be used from multiple classes, then make the target bitmap as global in your class and make the method as private void, this will save more memory.

And then call this method in a loop passing two Bitmaps at a time. This approach will help you to merge the Bitmaps in your desired order that too by having at most 3 instance of active Bitmaps at a time.

Upvotes: 0

Related Questions