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