OutOfMemoryError and downsampling in 2.7 beta

Creaky

Member
Licensed User
Longtime User
Hi Erel!

I'm currently working on an app that uses very large images, and on some of my test devices these images cause unpredictable OutOfMemoryError problems.
So you can imagine that I was really looking forward to the new automatic downsampling functionality to prevent OutOfMemoryError errors!

It does it's job well, but (there is always a but)...
In b4a 2.50 I was able to use 3000x3000px bitmaps on almost ALL of my test devices without running into OutOfMemoryError's . But with b4a 2.7 beta I'm only able to use 2000x2000px images before the downsampling functionality kick in! That's a 33% decrease in usable image size, while the 3000x3000px images did not cause OutOfMemoryError's before.

Is there a way to control the 'cut-off' threshold of the downsampling functionality? If not, is it still possible to ask for one in the 2.7 release version?
 

Asmoro

Active Member
Licensed User
Longtime User
I'm just joking Erel about my wish, but using 'ExitApplication' after reading the
purpose of it, is extreme and unreliable regarding to my app and therefor a big 'no no'.
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
An ImageView especially optimised for use with large bitmaps without having to use complicated tiling mechanisms.

I'm not familiar with TouchImageView, so you learn me how it works. But I'm a bit surprised that it is "especially optimized" for large bitmaps because I see no functions to handle the bitmap loading (you pass the bitmap as a parameter) and no functions to help to reduce the bitmap size (by cropping it, reducing its colors or resizing it). Maybe the library resizes the bitmap internally or uses a cropping system for the zoom in/out. I cannot say.

A 3000x3000 image occupies in memory 3000x3000x4 bytes = 34,33 Mo. Add a few MB for your app and you're pretty sure to get an Out of Memory error on a lot of devices with such a resolution. Even before trying to pass it to TouchImageView. So I don't know on what devices you tested your app but they were not old or low-cost ones.
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
I tried TouchImageView and here's the result with a PNG of 2510x3248 32bit on one of my devices (a basic phone). Theoretically the image should need 32 609 920 bytes of memory.

Free memory: 38MB
After opening the demo: 34 350 824
After loading the bitmap: 1 792 840
After passing it to TIV: 1 792 496
After zooming/moving many times: 1 648 424

I don't see any optimization for large bitmaps. Since the bitmap is fully loaded into memory, it is easy to play with.
The optimization must be done before, when you load the bitmap. It's where you can encounter an OoM.
 
Upvote 0

Creaky

Member
Licensed User
Longtime User
I'm not familiar with TouchImageView, so you learn me how it works. But I'm a bit surprised that it is "especially optimized" for large bitmaps because I see no functions to handle the bitmap loading (you pass the bitmap as a parameter) and no functions to help to reduce the bitmap size (by cropping it, reducing its colors or resizing it). Maybe the library resizes the bitmap internally or uses a cropping system for the zoom in/out. I cannot say.

A 3000x3000 image occupies in memory 3000x3000x4 bytes = 34,33 Mo. Add a few MB for your app and you're pretty sure to get an Out of Memory error on a lot of devices with such a resolution. Even before trying to pass it to TouchImageView. So I don't know on what devices you tested your app but they were not old or low-cost ones.

True, I did not test the app on low-cost devices. I'm testing on a SGS2 and a Nexus 7. Both can handle the 3000x3000px bitmaps without problems.

You've done some research regarding the memory usage of TIV, thanks for that, I hadn't done that yet. I was under the impression that Warwound optimized the view to handle large bitmaps and maintain good performance. Performance is great, but there are apparently no optimizations regarding memory usage. So your prediction that the app will cause problems on low tier devices is likely to be true.

As you can see from my profile I'm still a 'Rooky' B4A dev and lack the skills to build and implement a tiling mechanism. If you could help me out with that I would be very grateful :)
 
Last edited:
Upvote 0

Informatix

Expert
Licensed User
Longtime User
If you load your bitmap in a ImageView, set the gravity to FILL and resize your ImageView, you'll get the same memory usage as with TIV. There's no optimization in this library, but that doesn't mean that Warwound did a bad job. His lib works pretty well and can be easily recommended.

If you want to load bigger bitmaps into your app, or if you want to save memory and keep the possibility to zoom in/out at will, without a complex technique, there are not a lot of options: you can reduce the colors (using a JPG format, for example, instead of PNG or using the ReduceColors function of my Accelerated Surface lib) or you can sample the image down (but you lose sharpness). Professional apps use more advanced techniques. One of them, not very difficult to do, is to split your image into different parts while loading it, and saving them on disk. The image that you display first is a scaled down version. When the user zooms in, you start to rescale this image until you reach the maximum level of detail, then you replace your image by the corresponding part saved on disk, and you continue to zoom on that part. When it's well done, you should not notice the switch.

A lot of phones have only 32 MB of max heap memory (=the maximum memory that Java will allocate to your program). Older ones may have 24 MB and even 16 MB, but they become more and more uncommon. Recent phones and tablets have usually 48MB, 64MB or more. Depending on what your target, you can be short on memory.
 
Last edited:
Upvote 0
Top