Android Bitmap Load Large size picture (essence one)

Source: Internet
Author: User

Compression Reason:

1.imageview size If it is 200*300 then loading a 2000*3000 picture into memory is obviously a waste of shameful behavior;
2. The most important thing is that when the picture is too large, loading the original image directly causes an Oom exception (out of memory overflow)


So generally for large graphs we need to do the compression processing
Authoritative handling methods refer to the big picture processing tutorials in the Android Developer Center
Http://developer.android.com/training/displaying-bitmaps/load-bitmap.html


If you do not understand English, Wood has a relationship, this article will introduce




The main processing ideas are:
1. Get the pixel width of the picture (does not load the picture into memory, so it does not occupy resources)
2. Calculate the proportions that need to be compressed
3. Press to compress the picture in calculated proportions and load it into memory for use


The corresponding code in the Guenter picture loading tutorial (above URL) is:

/*** Get compressed pictures *  @param  res*  @param  resId*  @param  reqWidth              Required picture compression size min width *  @param  reqHeight             Required picture compression dimensions min. height *  @return */public static bitmap decodesampledbitmapfromresource (Resources res,  int resId,        int reqwidth, int reqheight) {       //first do not load the picture, just get the picture size     final bitmapfactory.options Options = new  bitmapfactory.options ();    //when Injustdecodebounds is set to true, pictures are not loaded only get picture size information     options.injustdecodebounds = true;    //Only the picture information will be saved to the options object, Decode method will not return the bitmap object     Bitmapfactory.decoderesource (res, resId, options);     //Calculate compression ratios, such as insamplesize=4, The images are compressed into the original 1/4    options.insamplesize = calculateinsamplesize (options, Reqwidth, ReqheighT);     //when Injustdecodebounds is set to False, Bitmapfactory.decode ... The picture object is returned     options. injustdecodebounds = false;    //to get the compressed Picture object using the calculated scale value     return bitmapfactory.decoderesource (res, resId, options);}    code: The core approach is bitmapfactory.decode ... (......, options) ... In addition, there are a series of decodefile/decodestream and so on, are using the options flexible analysis to obtain the image, but the source of the analysis of the picture is different, such as the network image acquisition, is generally the analysis of the byte stream information and then decode to obtain a picture instance  options is the picture configuration information, parameters in detail under:injustdecodebounds  whether to resolve only the boundary
When set to true, go to decode to get the picture, only load pixel width height information
When set to False decode will load the picture completely
Insamplesize Compression ratio
such as the original 200*300, if the value is 2 o'clock will be compressed into 100*150; is 4 picture compressed into 50*75
Preferably a power of 2, such as 2 4 8 16 .....
Outheight Picture Original height
Outwidth Picture Original width
The other parameters are self-researched, and here are only a few


The three-segment code within the Decodesampledbitmapfromresource method corresponds to the three-step process above
The difficulty lies in the middle step, the calculation of compression ratio, the official website also provides a calculateinsamplesize method
Where Reqwidth and reqheight are required for the picture to limit the minimum width to high value
/*** calculate compression scale values *  @param  options       Parse picture configuration information *  @param  reqWidth              Required picture compression size min width *  @param  reqHeight            Required Picture compression dimensions min. height *  @return */public static int calculateinsamplesize ( Bitmapfactory.options options,             int reqwidth, int  reqheight) {       //Save picture Original width high value        final int  Height = options. outheight;       final int width = options. outwidth;        //Initialization compression ratio is 1       int insamplesize = 1;        //When the picture width height value any one larger than the desired compressed picture width high value, enter the Loop computing system        if  (Height > Reqheight | | Width > Reqwidth) {              finAl int halfheight = height/2;             final int  halfwidth = width/2;              //Compression scale value increased by twice times per cycle,  & nbsp;          //until half of the original width and height is divided by the compression value is greater than the desired width and height              while  ((halfheight/insamplesize) >= reqheight                        && (halfwidth/insamplesize) >= Reqwidth) {                  insamplesize *= 2;             }      }        return  Insamplesize;} Use this method to obtain the desired compression scale value, and finally get to the compressed picture ~   the above code can understand, the following paragraph/* Tear//can skip/* Logic is the original width and height of half of the reduction, has been reduced to the width of the height is less than the limit of their own set width, so far, The problem with the test is the original 400*300, I limit the value 200*150,if meet enter, while loop for the first time, 400/2/1=200 not meet > Conditions ~ EndLoop, and finally returned a insamplesize=1 to me   Mactan I limit the value is just half of the original image, you should return to me 2 Ah ~ you finally return 1 to me, the compressed processing of the figure is still 400*300!!!   When I change the limit value slightly to become 195*145 slightly lower a little bit when ~if satisfied enter, while loop for the first time, 400/2/1>195 meet ~ Then the compression ratio 1*2 becomes 2, in the next while loop does not meet the end of the condition, Finally returns the scale value 2~ to meet the compression expectations   Official Website This method is: Compress half of the picture until it is compressed into the lowest value that is greater than the desired width and height
Greater than ~ is not greater than equals, so will appear in my case above, I think the method is not too good = = can meet the requirements of compression, but the proportion of compression is not accurate ~
So it is better to change to greater than equals, as follows (personal opinion, for reference only, in the actual compression is rarely encountered in this case, so the difference between > and >= is not large ~ See me this is a drag on the calculation of the proportion of logic to deepen the understanding of it)
while ((halfheight/insamplesize) >= reqheight && (halfwidth/insamplesize) >= reqwidth) {in SampleSize *= 2;}

Optimization:
Or the above example, if the 200*150 is limited, and the original is 390*290 what is the situation?
Or the first while loop, the 390/2/1 result is 195 does not satisfy the >200 situation, the end loop, the scale value is 1, the last picture compressed into 400*300
Although compression is not satisfied after one time is greater than the required width, but with the required width is very close to AH!!!
Can you make a proportional value that gets compressed to the nearest desired width and height?
I do not know = = back can slowly study, the definition of "close" is more vague, not good grasp ~
Find a few well-known pictures loaded open-source framework found that there is no such treatment-do not know that the design is not necessary, or no use
*/

----------------------------------------------------------


Above, the pixel size of the picture has been scaled, but the size of the picture is related to the pixel, but also to the color style.
Different styles determine the number of bytes per pixel in a picture
For example, the image default color style is argb_8888, each pixel occupies 4byte (bytes) size
Reference: http://developer.android.com/reference/android/graphics/Bitmap.Config.html

You can see a total of four color styles
Alpha_8 per pixel as long as 1 bytes ~ Unfortunately only represents transparency, no color properties
argb_4444 2 bytes per pixel ~ Color with transparency ~ Unfortunately, it's not officially recommended.
argb_8888 4 bytes per pixel ~ Color with transparency, default color swatch
rgb_565 2 bytes per pixel ~ Color without transparency
The default is argb_8888, if you want to continue to reduce the size of the image is not required transparency parameters,
Then you can set the color style to rgb_565.

The Setup method is in Bitmapfactory.decode. When you get a picture case
Modifying the Inpreferredconfig parameter of a configuration parameter
Opts.inpreferredconfig = Bitmap.config. rgb_565;

----------------------------------------------------------

Would you like to have a try and compress the pictures yourself?
To be aware of the problem, if you test with res fragments, you will find the picture size is a bit confusing.
That's because the images in the Drawable-*dpi folder automatically zoom in and out according to the corresponding screen density values.
For example, placed in the drawable-hdpi picture, directly without compression bitmapfactor.decode. Out, you'll find that the bitmap's width is 2/3 of the original,
When you test the picture, remember to put it under the drawable bag (not a new one under your own res), or you will be confused by the strange wide-high value
Refer to source code for specific change reasons, or search online

There is the Bitmapfactory.decodestream method will occasionally parse the picture failed (as if the Android low version of a bug) the recommended practice is to convert the stream to byte stream processing, and then use the Decodebytearray method to get the picture
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.