Android Background Image Memory Usage

Android background image memory usage

Is that why it's making the image so big?

Well, what's happening is that setBackgroundResource(R.drawable.blockbackgroundbottom1) is going to cause Android to first do the BitmapFactory.decodeResource() thing you that experimented with, but then have the rendering logic scale the image to apply it as a background. So, for example, the 3MB difference between the Galaxy Nexus and the Nexus S probably reflects the size difference, in pixels, between the renditions of the LinearLayout.

There may also be some resampling going on based on screen density, depending upon where you have stored this image in your resource tree.

Is there any way to make it keep the original image size in any way?

Off the cuff, I would first try putting it in res/drawable-nodpi/ (to prevent any automatic density-based resampling), then manually get the Bitmap via the version of BitmapFactory.decodeResource() that takes the BitmapFactory.Options, so you can get it scaled as it is being read in. If that does not seem to help much, you may need to move the PNG out of drawable resources and into a raw resource or assets, as Android might still try holding onto an un-scaled copy of the image. I don't think that it will if you use BitmapFactory.decodeResource() directly yourself, but I cannot rule it out.

How to reduce the memory usage of background images?

You can try converting your drawable to a bitmap

and then using BitmapFactory.Options to reduce the sample size, etc.

OutOfMemory when loading large Background Image

Please have a look at my related question:

High resolution Image - OutOfMemoryError

Try to minimize the memory usage of your application by keeping the background image as small as possible.

This can be done via:

  • cropping the image so that it fits the screen
  • compress the image further (use e.g. photoshop) before even using it in the app
  • use the below method to load your bitmap
  • recycle the bitmap as soon as you no loger need it
  • make sure you do not keep multiple instances of it in memory
  • set the reference to null after using the bitmap

Make sure the images you set as a background are loaded properly (e.g. cropped in size, for example fit the screen size) and released from the memory as soon as they are no longer needed.

Make sure you have only one instance of your Bitmap in memory. After displaying it, call recycle() and set your reference to null.

This is how you could load your images:

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

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

Thanks to Adam Stelmaszczyk for this beautiful piece of code.

Android still uses excessive memory when loading background image

The trick to getting BitmapFactory to give you a low-memory image is to fill in inSampleSize on the BitmapFactory.Options. This tells BitmapFactory to downsample the image as it loads, giving you a lower-resolution image, but one that is better tuned to whatever use you plan to put it to. You would need to calculate the desired inSampleSize that you want, based on the resolution of the ImageView (or whatever) that you are using the image for.

This sample app demonstrates loading some images out of assets/ with different inSampleSize values.

Memory problems with background images despite small size

The size of the image file in KB is not directly relevant to this issue, but the size of the image in pixels along other factors as well.
So if you want to reduce memory consumption, the easiest way would be to use images with smaller dimensions.

This question might help you:

Android background image memory usage

Do SetBackgroundDrawable load image in memory?

Of course, it does. All you see on display is stored im memory. After you set the background it is immediately loaded. Either while inflating from xml or when setting explicitly. Don't use images larger than needed as a resource. And try to avoid large HQ images where possible.

Why does the normal pictures allocated a lot of memory?

This problem can be solved using drawable-nodpi, look this:

Android background image memory usage

In android background image does not change when orientation does

Rather than switch the drawable upon orientation change, you can instead switch the layout. By placing an xml file of the same name in the layout-land/ folder, the OS will load this alternate layout when the screen orientation is landscape. That way, you will always be using the correct drawable (as they can be specified differently in each of the two xml files), and there is the added advantage that you can independently optimize your layout for both orientations!

This post on the Android Developer's blog suggests some tips and tricks on how to retain objects upon orientation change and avoid memory leaks in the process; which will be of further assistance to you.

Memory efficient way to show a low quality image

All variants are same because you use background tag.

With image view you should use android:src for usual drawable or app:srcCompat for vector drawable. Also you can scale by scaleType.

ImageView vs AppCompatImageView:

The second one has backports for some features from new Apis.



Related Topics



Leave a reply



Submit