Android bitmapfactory's outofmemoryerror: bitmap size exceeds VM budget solution

Source: Internet
Author: User

This error is sometimes encountered when decoding an image using bitmapfactory provided by Android, namely, java. Lang. outofmemoryerror: bitmap size exceeds VM budget. This is often caused by an excessively large image. For normal use, one way is to allocate less memory for storage. That is, when loading images, the images are scaled down at the cost of image quality, this is also the solution adopted by many people to avoid the above oom. However, this method is not worth the candle. We didn't say anything when we use images as thumbnails. But what should we do when we need to provide image quality?Java. Lang. outofmemoryerror: bitmap size exceeds VM budget really makes many people cry! A few days ago, I had a requirement to load the image on the SD card.

First, use

 
Bitmap BMP = bitmapfactory. decodefile (pepicfile. getabsolutepath () + "/" + info. getimage ());

The above parameter is the image file and path to be read. When the file is small,ProgramIt works normally, but when I select a large image, the program immediately jumps out.Java. Lang. outofmemoryerror: bitmap size exceeds VM budget OOM error!

On Android devices (where you have only 16 MB memory available), If you useBitmapfactory decodes a large file, which may occur in large cases. So, how can this problem be solved ?!

First, let's talk about a method that we mentioned earlier: shrinking the image to be loaded at the cost of image quality. There is an internal class in bitmapfactoryBitmapfactory. Options. When options. insamplesize is greater than 1:

If set to a value> 1, requests the decoder to subsample the original image, returning a smaller image to save memory. (1-> decodes full size; 2-> decodes 1/4th size; 4-> decode 1/16th size ). because you rarely need to show and have full size bitmap images on your phone. for manipulations smaller sizes are usually enough.

that is, options. insamplesize is scaled down based on the reciprocal of the 2 Index. In this way, we can rely on the setting of the value of insamplesize compresses the image and loads it. In this way, the aforementioned OOM problem will not occur. Now the question is how to determine value of insamplesize? The scale-down ratio of each image should be different! In this case, it must be dynamically determined during running. In bitmapfactory. options provides another member, injustdecodebounds.

Bitmapfactory. Options opts = new bitmapfactory. Options (); opts. injustdecodebounds = true; Bitmap bitmap = bitmapfactory. decodefile (imagefile, opts );

After injustdecodebounds is set to true, decodefile does not allocate space, but the length and width of the original image can be calculated, that is, opts. Width and opts. Height. With these two parametersAlgorithmTo obtain an appropriate insamplesize.Android provides a dynamic computing method. As follows:

Public static int computesamplesize (bitmapfactory. options options, int minsidelength, int maxnumofpixels) {int initialsize = values (options, minsidelength, maxnumofpixels); int roundedsize; If (initialsize <= 8) {roundedsize = 1; while (roundedsize <initialsize) {roundedsize <= 1 ;}} else {roundedsize = (initialsize + 7)/8*8;} return roundedsize;} Private Static int com Puteinitialsamplesize (bitmapfactory. Options options, int minsidelength, int maxnumofpixels) {double W = options. outwidth; double H = options. outheight; int lowerbound = (maxnumofpixels =-1 )? 1: (INT) math. Ceil (math. SQRT (w * H/maxnumofpixels); int upperbound = (minsidelength =-1 )? 128: (INT) math. min (math. floor (W/minsidelength), math. floor (H/minsidelength); If (upperbound <lowerbound) {return lowerbound;} If (maxnumofpixels =-1) & (minsidelength =-1 )) {return 1;} else if (minsidelength =-1) {return lowerbound;} else {return upperbound ;}}

For the above reference, we only need to use this function:

 
Bitmapfactory. options opts = new bitmapfactory. options (); opts. injustdecodebounds = true; bitmapfactory. decodefile (imagefile, opts); opts. insamplesize = computesamplesize (OPTs,-1,128*128); // you must set it back to false because it was previously set to trueopts. injustdecodebounds = false; try {bitmap BMP = bitmapfactory. decodefile (imagefile, opts); imageview. setimagebitmap (BMP);} catch (outofmemoryerror ERR ){}

In this way, the above OOM error will not be reported at bitmapfactory. decodefile execution. Perfect solution? As mentioned above, this method is at the cost of image quality to some extent. How can we achieve more Optimized requirements?

When a large image resource is loaded on an Android device, you can create a temporary space to load the loaded resource into the temporary space.

 
Bitmapfactory. Options bfoptions = new bitmapfactory. Options (); bfoptions. intempstorage = new byte [12*1024];

A temporary space of 12 KB is created. Then bitmap bitmapimage = bitmapfactory. decodefile (path, bfoptions) is used. However, the above problems still occur in the program! The following uses bitmapfactory. decodefiledescriptor to solve the above problems:

Bitmapfactory. options bfoptions = new bitmapfactory. options (); bfoptions. indither = false; bfoptions. inpurgeable = true; bfoptions. intempstorage = new byte [12*1024]; // bfoptions. injustdecodebounds = true; file = new file (pepicfile. getabsolutepath () + "/" + info. getimage (); fileinputstream FS = NULL; try {FS = new fileinputstream (File);} catch (filenotfoundexception e) {e. printstacktrace ();} bitmap BMP = NULL; If (FS! = NULL) Try {BMP = bitmapfactory. decodefiledescriptor (FS. getfd (), null, bfoptions);} catch (ioexception e) {e. printstacktrace ();} finally {If (FS! = NULL) {try {fs. Close ();} catch (ioexception e) {e. printstacktrace ();}}}

Of course, the obtained image can be scaled or displayed in the BMP obtained above.

PS: reclaim memory after image processing . BMP. recycle (); this releases the memory resources occupied by images.

hellope: http://www.cnblogs.com/hellope

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.