1

I have a .png file I would like to use in my app. This image is rather huge, approximately 328x32765 pixels, 751KB in size and is in my res folder. I get an error message of "java.lang.OutOfMemoryError: bitmap size exceeds VM budget" from trying to set this image into my layout.

I am not sure if it is relevant, but I also have about 730 buttons on that same page, that load and work ok, but I am thinking that maybe those buttons are using a lot of memory as well?

Either way, is there a simple fix to help solve this issue or make my .png image use less memory?

bmjohns
  • 6,344
  • 1
  • 33
  • 39
  • Take a look in here. http://stackoverflow.com/questions/7021578/resize-drawable-in-android – Lawrence Gimenez Oct 04 '12 at 02:30
  • Why is the image that tall? Is the user supposed to be able to scroll up and down on it? If so, you might want to try chopping it up into smaller slices, and putting them into a listview, which will then load only the visible slices. – Andy Oct 04 '12 at 02:31
  • I think the listview could be a good solution andy, only problem is that that will require a decent amount of work for me, and I am simply making an app for free for a friend with a very tight schedule. So I may have to look for easier options. – bmjohns Oct 04 '12 at 04:03
  • @user753964, considering the amount of time you'll spend to research, trial and error. I think ListView will be your lifesaver and timesaver. The number of lines to implement it is under 20 lines - decently small. – Nar Gar Oct 04 '12 at 04:18
  • I guess my reservations to implementing this method is that I have a lot of other layouts on the page that coincide with my scrollview, so while the actual implementation is rather simple, the larger implications of what it changes on my app is a little more. But I may end up using this method anyways, and if not, I know to use it next time. Thanks for the responses! – bmjohns Oct 04 '12 at 19:30

3 Answers3

2

A bitmap takes a lot of memory as mentioned in the tutorial from the android's site itself regarding bitmaps

Displaying Bitmaps

EDIT:

Try using the function "Bitmap.createScaledBitmap(Bitmap, width, height, filter);" or try to use the "BitmapFactory.Options" class as mentioned in the tutorial.

"BitmapFactory.Options" class helps a lot since its function itself helps developers to minimize the use of VM in loading Bitmaps by caching the loaded bitmap.

gorbos
  • 311
  • 1
  • 7
  • I got the bitmap factory.options class to work with loading in my image, but if I want the image to be the size it needs to be I still get the VM error. If I remove the 730 buttons on the scroll view that I am trying to load this image on, will that help me not get a VM error? – bmjohns Oct 04 '12 at 04:00
  • No, removing 730 buttons will not help, since the VM complains about not being able to allocate the requested memory AT ONCE. With smaller objects android is smart enough to init and discard (page onto a "virtual memory") as needed. – Nar Gar Oct 04 '12 at 04:11
  • Nar Gar is right, the problem is, your app itself eats the allocated memory that was given to the app. In your case, if I'm not mistaken, the bitmap that you mentioned is the main source of the error so you don't have to look at your buttons, unless those buttons too have their own bitmap. In another note, do you load multiple bitmaps in your app using the Bitmap class? If that is the case, then why not try looking at that part of the code. Every time that the app laods a Bitmap aside from the drawable folder, the app tends to eat lots of memory. – gorbos Oct 04 '12 at 05:34
  • I have 2 custom images for my buttons, one for when its sitting there and another for when it is pressed. Each button uses those same images though, but I am not reading them in as a bitmap, rather just pointing to the res source directly from the XML. But I better understand how memory is allocated in the phone now. – bmjohns Oct 04 '12 at 19:48
0

Although your image is 731KB big, the actual inflated bitmap size will be almost 41 megabytes. You get the error because the device is unable to allocate 41MB at once.

Unfortunately, there is no other way to work this out except by loading a scaled down version of the image.

Use Bitmap.Options class and specify a scaled factor:

2 - means make each side twice smaller

3 - three times smaller,......

x - x times smaller

the good news is that the resulting inflated bitmap size will be 41/(x * x)MB:

2 - 41/4 = 10.25MB

3 - 41/9 = 4.5MB

4 - 41/16 = 2.6MB .....

try this out and test on multiple devices.

Alternatively, break down the image into considerably smaller images and use a ListView with no borders or dividers, such that you'll still see a smooth image but the ListView will also take care of initiating and discarding the pieces as they are needed. (Note that you'll loose the capability of horizontal scrolling because ListView scrolls vertically only - just in case this is a concern for you).

Nar Gar
  • 2,591
  • 2
  • 25
  • 28
0

Android cant handle large bitmaps OOM error will occur.Its not an a=unexpected error this is a big problem faced by many developers.try Googling many docs you will find explianing about the OOM error.I had also struggled while developing an application.For Removing this, sampling big images is the only one way.

   int scale = "Image byte length" / 320000;
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = scale / 2 + scale % 2* 2;
   decryptedimage=BitmapFactory.decodeByteArray(decryptedData,0,decryptedData.length,options);
Sreedev
  • 6,563
  • 5
  • 43
  • 66