Zimon
Zimon

Reputation: 43

A 320kb background image takes up roughly 30MB memory space

At the moment I am working on a application that is supposed to run on both tablet and phone. The resolution of my main menu background image is 2000x1250, and it is resized depending on the canvas width and height. The size of the image is 320KB (PNG). However, should the resolution be 2000x1250, the dalvikm allocator allocates up a whopping 30MB of memory for this single background image. I've read and applied the article http://developer.android.com/training/displaying-bitmaps/load-bitmap.html, but the amount of memory located remains the same when the resolution is 2000x1250 (I test this on my S3 with a resolution of 1280x720). Is this something I should worry about? Do tablets have more space for bigger bitmaps?

Thanks in advance, -Z

EDIT1:

LOGCAT

Application starts

02-08 20:35:12.105: D/dalvikvm(27962): GC_FOR_ALLOC freed 8804K, 18% free 53293K/64775K, paused 31ms, total 31ms

02-08 20:35:12.110: I/dalvikvm-heap(27962): Grow heap (frag case) to 61.693MB for 9000016-byte allocation

02-08 20:35:12.145: D/dalvikvm(27962): GC_CONCURRENT freed 35206K, 59% free 26875K/64775K, paused 11ms+3ms, total 32ms

02-08 20:35:12.315: D/dalvikvm(27962): GC_FOR_ALLOC freed 0K, 59% free 26875K/64775K, paused 10ms, total 10ms

This is where the main menu is openend

02-08 20:35:12.330: I/dalvikvm-heap(27962): Grow heap (frag case) to 61.643MB for 36000016-byte allocation

02-08 20:35:12.350: D/dalvikvm(27962): GC_CONCURRENT freed 0K, 5% free 62031K/64775K, paused 11ms+3ms, total 23ms

Functions from the tutorial:

public static int calculateInSampleSize(
        BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;

if (height > reqHeight || width > reqWidth) {

    // Calculate ratios of height and width to requested height and width
    final int heightRatio = Math.round((float) height / (float) reqHeight);
    final int widthRatio = Math.round((float) width / (float) reqWidth);

    // Choose the smallest ratio as inSampleSize value, this will guarantee
    // a final image with both dimensions larger than or equal to the
    // requested height and width.
    inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}

return inSampleSize;
}

 public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
        int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
 }

My Code in the OnCreate (don't mind the deprecation, that's not the issue):

final FrameLayout fr = (FrameLayout) findViewById(R.id.mainmenu_background);
//fr.setBackgroundResource(R.drawable.background_main_menu);
Display display = getWindowManager().getDefaultDisplay();
//Point size = new Point();
//display.getSize(size);
fr.setBackgroundDrawable(new BitmapDrawable(getResources(), decodeSampledBitmapFromResource(getResources(), R.drawable.background_main_menu, 2000, 1250)));

And the code in the XML:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/mainmenu_background"
>

Any ideas?

Upvotes: 2

Views: 1197

Answers (1)

rekire
rekire

Reputation: 47945

The reason is very simple an image needs 4x2000x1250 bytes of memory. Each pixel has a part of red, green, blue and alpha channel information.

30 MB is a bit strange but 9MB would be normal: 4x2000x1250=10000000 Byte -> 9,5MB

Sure that you don't leek somewhere memory?

In general it is better to use a smaller image. There is a technique called 9-patch to stretch images automatically.

Upvotes: 2

Related Questions