First, why do bitmap need to load efficiently?
Now the big picture of high-definition, often will be several m, and Android to a single application of the memory limit, only a small dozens of m, such as 16M, which caused the loading of bitmap is prone to memory overflow. The following exception information is often required in development:
Java.lang.OutofMemoryError:bitmap size exceeds VM budget
In order to solve this problem, there is a bitmap efficient loading strategy. In fact, the core idea is simple. Suppose through the ImageView to display the picture, many times ImageView does not have the original picture size so big, this time the entire picture to load in then sets to ImageView, obviously is not necessary, because ImageView has no way to display the original picture. This time can be a certain sample rate to reduce the image and then load it in, so that the picture can be displayed in ImageView, but also reduce the memory footprint to avoid oom to a certain extent, improve the performance of bitmap loading.
Second, the specific way of bitmap efficient loading 1. How to load Bitmap
Bitmap is a picture in Android's middle finger. The class four methods provided by the Bitmapfactory class are: Decodefile,decoderesource,decodestream and Decodebytearray, respectively, from file system, resource, An Bitmap object is loaded in the input stream and byte array, where Decodefile,decoderesource calls the Decodestream method indirectly, and the four methods are eventually implemented at the bottom of Android, Corresponds to several native methods of the Bitmapfactory class.
parameter of 2.bitmapfactory.options ①insamplesize parameter
The above four types of methods all support bitmapfactory.options parameters, and bitmap by a certain sample rate of scaling is achieved through the Bitmapfactory.options parameter, the main use of the insamplesize parameters, that is, the sampling rate. By setting the insamplesize, the pixels of the picture are scaled in height and width.
When insamplesize=1, the size of the picture after the sample is the original size of the picture. is less than 1 and is calculated as a result. When Insamplesize>1, the sampled image will be scaled down to a scale of 1/(Insamplesize two).
For example: A picture of 1024x1024 pixels, stored in ARGB8888 format, memory size 1024x1024x4=4m. If insamplesize=2, then the sampled image memory size: 512x512x4=1m.
Note: Official document spending, insamplesize should always be 2 of the index, such as 1,2,4,8. If the value of the incoming insamplesize is not 2, then the system will be rounded down and selected as the nearest 2 index instead. For example, 3, the system will choose to replace. The experience was not established on all Android versions at that time.
Notes on Insamplesize: Generally, the width and height of the image are calculated according to the actual size/width and height of the picture. However, you should take the minimum zoom ratio to avoid scaling the picture too small to reach the specified control, which is not covered, and requires stretching to cause blurring.
For example: the size of the ImageView is 100x100 pixels, and the original size of the picture is 200x300, then the width scaling ratio is 2, and the high scaling ratio is 3. If the final insamplesize=2, then the scaled picture size 100x150, still suitable imageview. If insamplesize=3, the scaled image size is smaller than the desired size of imageview, so the image is stretched to blur.
②injustdecodebounds parameters
We need to get the width height information of the loaded picture and then give the insamplesize parameter a zoom ratio. Then how can not load the picture but can get the picture of the width of the information, through the injustdecodebounds=true, and then load the picture can be realized only the image of the width of the high information, does not really load the picture, so this operation is lightweight. When you get the width and height information, calculate the zoom ratio, and then reload the picture after you injustdecodebounds=false the image, you can load the zoomed image.
Note: Bitmapfactory gets a picture of the width of the information and the location of the picture and the program to run the device, such as the same picture placed in a different drawable directory or program running on different screen density devices, can lead to bitmapfactory to obtain different results , and the resource loading mechanism for Android.
3. Efficient loading of bitmap processes
① sets the bitmapfactory.options injustdecodebounds parameter to True and loads the picture.
② the original width-height information of the picture from the Bitmapfactory.options, which corresponds to the outwidth and Outheight parameters.
The ③ calculates the sample rate insamplesize based on the rule of the sampling rate and the desired size of the target view.
④ set the bitmapfactory.options injustdecodebounds parameter to False, and then reload the picture.
Three, bitmap high-efficiency load code implementation
Public StaticBitmap Decodesampledbitmapfromresource (Resources res,intResId,intReqwidth,intreqheight) {bitmapfactory.options Options=Newbitmapfactory.options (); Options.injustdecodebounds=true; //Loading PicturesBitmapfactory.decoderesource (res,resid,options); //Calculating the zoom ratioOptions.insamplesize =calculateinsamplesize (options,reqheight,reqwidth); //Reload PictureOptions.injustdecodebounds =false; returnBitmapfactory.decoderesource (res,resid,options); } Private Static intCalculateinsamplesize (Bitmapfactory.options Options,intReqheight,intreqwidth) { intHeight =Options.outheight; intwidth =Options.outwidth; intInsamplesize = 1; if(Height>reqheight| | Width>reqwidth) { intHalfheight = HEIGHT/2; intHalfwidth = WIDTH/2; //calculates the zoom ratio, which is the exponent of 2 while((halfheight/insamplesize) >=reqHeight&& (halfwidth/insamplesize) >=reqwidth) {Insamplesize*=2; } } returninsamplesize; }
At this point, you can load images efficiently in the following ways:
Mimageview. Setimagebitmap (Decodesampledbitmapfromresource (Getresources (),R.mipmap. Ic_launcher, ( in);
In addition to the Decoderesource method of Bitmapfactory, other methods can be implemented similarly.
Iv. Reference Articles
Https://github.com/LRH1993/android_interview/blob/master/android/basis/bitmap.md
Android Interview Collection recording Android bitmap compression strategy