Android Question Downsampling of Images

Guardian17

Active Member
Licensed User
A game app that I'm working on causes problems on my Galaxy S3 smartphone. Regardless of the type of debug mode (Legacy, Rapid, or Release), after the app has started, I only need to change the Orientation two times when many "downsampling image" status lines then appear in the Log window.

If I add the
SetApplicationAttribute(android:largeHeap,"true")
line to the Manifest, there is an improvement, but the "downsampling image" status lines start appearing after the sixth orientation change.

On my Nexus 10 Tablet, the downsampling of images never seems to occur, (or at least it is more than 50 orientation changes -- I stopped at 51). Why is there a difference between the smartphone and tablet?

According to this post:
http://www.b4x.com/android/forum/th...memory-used-imageviews-bitmaps.49597/#content
bitmaps get released on orientation changes and there should not be memory issues, even if the user rotates the device many times.

Why am I allowed to change the orientation once without downsampling (or 5 times with the largeHeap), but then the downsampling occurs? Is this only related to the bitmaps/storage? If the bitmap memory is released, why does this occur at all?

The images are directly for my own use to provide information to the user while playing the game -- they are not, say, large photos for which I would then use "LoadBitmapSample" to give a smaller representation of a larger image.

Several of my bitmaps do go to 1500x750 in size.
Is there any guide to what a maximum bitmap size should be? The downsampling seems to occur only after an aggregate amount of memory is used, but what goes into this aggregate summation of memory use?

I have tried re-sizing the larger bitmaps (about 7 images are 1500x750) by decreasing their size by 50%, and that does make an improvement -- I can rotate the device 7 times with the largeHeap used, with the downsampling occurring on the 8th rotation.

---------
Additional related question: when the downsampling does occur, the status lines typically occur in groups like this:

Downsampling image due to lack of memory.
Downsampling image due to lack of memory: 2
Downsampling image due to lack of memory: 4

Downsampling image due to lack of memory.
Downsampling image due to lack of memory: 2
Downsampling image due to lack of memory: 4
Downsampling image due to lack of memory: 8
Downsampling image due to lack of memory: 16
Downsampling image due to lack of memory: 32

In the example above, is the downsampling occurring on TWO images, with multiple downsamples occurring on each image depending on its size (3 times for the first image that downsamples to "4", and 6 times for the second image that downsamples to "32"? (If the Image Names were to be shown, I would then know which images I would need to make smaller to avoid the downsampling -- I have added this to the WishList).
 
Last edited:

Guardian17

Active Member
Licensed User
OK. I thought I had found a reason for the issues I am seeing, but .....

I have an animation that runs when the app is first started. The animation consists of 43 images with each image being 534x854 pixels. According to the above memory calculation, that would be 534x854x4x43, or 78,438,192 bytes, assuming all of the images are in memory at the same time. This is above what I understand to be a 64MByte limit(?). But is the app actually consuming that much memory for this animation?

Each image is loaded into one single panel as the background image, in a sequence based on a timer tick and counter. So, for this animation, is the app consuming the 78.4 MBytes, or is it only using 534x854x4, or 1,824,144 bytes, which is the memory for one single image? AND, if I later Remove that panel in which the images are placed, does that memory get freed up again?

I have tried removing the animation completely from the app (from code, and from the IDE Files list, and physically from the project's Files folder), but I get EXACTLY the same results that I had gotten before, where the downsampling starts occurring on the 2nd orientation change (if no largeHeap set), and on the 6th orientation change (if largeHeap is used), on my Galaxy S3.

How are you defining and setting the Bitmaps? Can we see some code please?
While I appreciate that it would be helpful to post code, the entire game project is too big to upload. Most of the images get loaded via layouts, and I usually load them into panels as BitmapDrawables.

Why aren't you using LoadBitmapSample?
I would think (and I may very well be incorrect) that LoadBitmapSample is typically only used when you want to represent a large bitmap/photo in a much smaller view (when the size may change drastically), like if you were to have preview panes in a ListView of photos taken on a camera. I didn't think that LoadBitmapSample should be used for images for which I know the size of those images. I assume, then, that I would have to load the layout, and then follow that layout load by a LoadBitmapSample statement, since LoadBitmapSample can't be used in the Designer?

Images are supposed to be released when the orientation changes (unless there are still references to the images).
What would constitute remaining "references to the images" ?


Two remaining questions not yet answered:
Is there some guide to the maximum size of a bitmap?
Is the multiple downsampling being done on single bitmaps (1,2,4,8,16, etc), and if so, why are there so many downsamplings done?
 
Last edited:

Erel

Administrator
Staff member
Licensed User
The available memory for each process depends on the specific device you use.

Is there some guide to the maximum size of a bitmap?
As I wrote above it depends on the specific device.

When an out of memory error occurs when an image is loaded the image loader down samples the bitmap and tries again. If it still fails it will downsample it another time (up to 5 times).

You will need to make the images smaller. Loading many large images requires too much memory.
 
Top