Bitmap compression strategy

First, why the need for efficient load Bitmap?

Now high-definition big picture, should easily several M, and Android memory limit imposed on individual applications, only a small few dozen M, such as 16M, which results in time to load Bitmap is prone to memory overflow. The following exceptions, which is often needed in development:

java.lang.OutofMemoryError:bitmap size exceeds VM budget

To solve this problem, there have been efficient loading strategy of Bitmap. In fact, the core idea is simple. Assumptions to display pictures by ImageView, often ImageView not so much the size of the original picture, this time to load the whole picture and then set to come in ImageView, apparently is not necessary, because there is no way ImageView displays the original picture. This time we can at a certain sampling rate picture down and then loaded in, so the picture is displayed both in ImageView, as well as lower memory footprint to avoid OOM to a certain extent, improve the performance of Bitmap loaded.

Second, efficient loading DETAILED Bitmap

1. The way to load the Bitmap

Android Bitmap in the middle is a picture. The method provided by the BitmapFactory four categories: decodeFile, decodeResource, decodeStream and decodeByteArray, are loaded from the file system, resource, and the byte array input stream a Bitmap object, wherein decodeFile, decodeResource and indirect call decodeStream method, four the final method is based on the underlying Android-implemented method corresponding to several native BitmapFactory class.

2.BitmapFactory.Options parameters

①inSampleSize parameters

The above-mentioned four types of methods support BitmapFactory.Options parameters, and Bitmap be scaled by a certain sampling rate is achieved by BitmapFactory.Options parameters, the main use of the inSampleSize parameters, the sampling rate. By inSampleSize set the height and width of the pixels of the picture to zoom.

When inSampleSize = 1, i.e., the sampled image size of the original image size. Less than 1, but also according to a calculation.
When inSampleSize> 1, i.e., the sampled image will be reduced, at a scale of 1 / (inSampleSize quadratic).

For example: a 1024 × 1024 pixel image using ARGB8888 storage format, then the memory size of 1024 × 1024 × 4 = 4M. If inSampleSize = 2, then the memory size of the sampled image: 512 × 512 × 4 = 1M.

Note: The official document expenses, inSampleSize values ​​should always be 2 index, such as 1,2,4,8 and so on. If the incoming external inSampleSize value is not a power of two, the system will select and exponent rounding down to a nearest 2 instead. For example 3, the system will select 2 instead. Experience has shown that not all was set up on all Android versions.

The value of the Notes on inSampleSize:
usually based on the actual size of the picture width and height / width and height of the desired size, width and height were calculated zoom ratio. You should take the smallest scaling ratio, to avoid scaling image is too small, can not reach the specified control confluence, leading to blurred stretch required.

For example: ImageView size is 100 × 100 pixels, and the original image size is 200 × 300, as wide as the zoom rate is two, a high zoom ratio is 3. If the final inSampleSize = 2, then the picture size 100 × 150 scaled, still appropriate ImageView. If inSampleSize = 3, then the picture size ImageView scaled smaller than the desired size, so that image will be stretched resulting in blurred.

②inJustDecodeBounds parameters

We need to get a load of the picture width and height information, and then select the zoom ratio to inSampleSize parameter scaling. So how can not load the picture was able to get the first pictures of width and height information, by inJustDecodeBounds = true, then load the picture resolution can be achieved only picture width and height information, and not the real picture is loaded, so this operation is a lightweight of. When the acquired width and height information, the scaling ratio is calculated, and then the inJustDecodeBounds = false, and then reload the picture, you can load a scaled picture.

Note: BitmapFactory equipment acquired wide picture information and pictures of high position and running about, such as the same picture in different drawable directory or programs run on different screen densities of the device, may lead to a different acquisition BitmapFactory As a result, loading mechanism and resources related to Android.

3. Efficient processes loaded Bitmap

① the BitmapFactory.Options of inJustDecodeBounds parameter is set to true and Load picture.

② BitmapFactory.Options removed from the original image width and height information, which correspond to outWidth and outHeight parameters.

③ According to the regular sampling rate and the required size of View binding target sample rate is calculated inSampleSize.

④ will BitmapFactory.Options of inJustDecodeBounds parameter set to false, then load the picture again.

Three, Bitmap achieve efficient code loaded

      
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
      
      
public static Bitmap (Resources res, int resId, int reqWidth, int reqHeight){
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res,resId,options);
// Calculate the scaling ratio
options.inSampleSize = calculateInSampleSize(options,reqHeight,reqWidth);
// reload picture
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res,resId,options);
}
private static int calculateInSampleSize(BitmapFactory.Options options, int reqHeight, int reqWidth) {
int height = options.outHeight;
int width = options.outWidth;
int inSampleSize = 1;
if(height>reqHeight||width>reqWidth){
int halfHeight = height/ 2;
int halfWidth = width/ 2;
//计算缩放比,是2的指数
while((halfHeight/inSampleSize)>=reqHeight&&(halfWidth/inSampleSize)>=reqWidth){
inSampleSize*= 2;
}
}
return inSampleSize;
}

This time it can by way of efficient Load picture:

      
      
1
      
      
mImageView.setImageBitmap(decodeSampledBitmapFromResource(getResources(),R.mipmap.ic_launcher, 100, 100);

In addition to decodeResource method BitmapFactory, and other similar methods can be achieved.

Original: Big Box  Bitmap compression strategy


Guess you like

Origin www.cnblogs.com/chinatrump/p/11615098.html