Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are all my bitmaps upsampled 200%?

I'm having severe memory issues in my application [1]. In order to investigate this, I took heapdumps of my app at different states. I saw that some bitmaps were taking huge amounts of memory. I wrote a small tool [2] that decodes the byte arrays to Windows bitmap files (.bmp), so that I can see the bitmaps and compare them to the files I have in my res/drawable folder.

What I discovered is that all my files are upsampled twice.
I first checked with the biggest one had: a byte array buffer of more than 9MB in the heap, which was decoded to be a nice 1920x1280 picture, while the original one was a 960x640 png file.
I tried with the second biggest, over 3MB, which once decoded showed a nice 754x1200 picture, the original size was... guess what? A nice 377x600 jpg file.

What gives?

I have enabled HW acceleration in my Android Manifest file (though I'm not sure I really need it, I'm just using some basic views and activities).
I'm running stock Android 4.0.2 on a GSM Galaxy Nexus (yakju). I'm receiving feedback from my testers that the issue is present on their 4.0.3 Nexus S, though I couldn't check their heap dumps yet.

I'm trying to save memory here, if Android doubles everything, no wonder the app crashes quickly because the heap usage gets too high (around 64MB in my case). I hope there's a reason and a way around it.

References:

  1. OutOfMemoryError when loading activities
  2. How to actually see a Bitmap taken from an Android heap dump
like image 955
Benoit Duffez Avatar asked Mar 08 '12 22:03

Benoit Duffez


1 Answers

When you put images in res/drawable, Android will assume they have a dpi of 160, i.e. it is the same as putting them in res/drawable-mdpi. Galaxy Nexus is an xhdpi device, i.e. it has a (generalized) dpi of 320. To compensate for the high resolution display, Android will upsample the images with 200%.

The solution is simple, just put the images in res/drawable-xhdpi instead. Then the declared dpi of the images will match the display you run on, and Android will not perform any scaling of the images.

Please refer to http://developer.android.com/guide/practices/screens_support.html for more info.

like image 196
Martin Nordholts Avatar answered Sep 24 '22 13:09

Martin Nordholts