catalogue
- 01. Let’s start with a needs analysis case
- 02.Bitmap memory Usage
- 03. Factors affecting Bitmap memory usage
- 04. Image loading method
- 05. Where did the loading image memory go
- 06. Specific steps to load pictures
01. Let’s start with a needs analysis case
- Case description
- Loading a local large image or web image, from loading Settings to View, how to reduce memory, avoid loading image OOM.
- Case analysis
- When displaying high resolution images, it is best to compress them first. The compressed image should be close to the size of the control used to display it. Displaying a large image on a small ImageView does not provide any visual benefit, but takes up valuable memory, and may have a negative impact on performance.
02.Bitmap memory Usage
- Network image calculates Bitmap memory size
- Bitmap Memory size = Image length x image width x Bytes per pixel
- Bitmap’ is usually encoded in two different ways: ARGB_8888 and RGB_565. ARGB_8888 has 4 bytes per pixel, and RGB_565 has 2 bytes. ARGB_8888 is usually used. The typical 1080 x 1920 image memory footprint is 1920 x 1080 x 4 = 7.9m
- Load local resources to calculate the Bitmap memory size
- Width * height * nTargetDensity/inDensity = width * height * nTargetDensity
- More details can be found in this article 04.Bitmap computational memory
- Exactly. What about this idea? The calculation formula is as follows
- For resource files: width * height * nTargetDensity/inDensity * nTargetDensity/inDensity * memory occupied by a pixel;
- Width * height * memory occupied by a pixel;
03. Factors affecting Bitmap memory usage
- Factors affecting Bitmap memory footprint:
- The final loading resolution of the image;
- Image format (PNG/JPEG/BMP/WebP);
- The drawable directory where the image is stored;
- Color mode for image property Settings
- Screen density of the device;
04. Image loading method
- There are generally three sources of obtaining images:
- 1. Load the file from the network. 2
- For these three cases we usually use BitmapFactory
- DecodeStream decodeFile, decodeResource, these three functions to get to the bitmap and then call the ImageView setImageBitmap function to show.
05. Where did the loading image memory go
- Think about it: Where is memory going (and why is it being consumed so much)?
- Each decode function in BitmapFactory generates a Bitmap object that holds the decoded image and returns the reference. If the image data is large, the bitmap object will apply for more memory. If the image data is too large, the memory will be insufficient, and the phenomenon of out of memory will naturally occur.
- Why is OOM easy?
- These methods by Decode of BitmapFactory attempt to allocate memory for bitmaps already built, which can easily result in OOM. To this end, each resolution method provides an optional bitmapFactory. Options parameter. Setting this to true disables the inJustDecodeBounds method from allocating memory to bitmaps and returning a bitmap object. But is null.
06. Specific steps to load pictures
- To avoid OOM exceptions, it is best to check the size of each image before parsing it, unless you trust the source of the image to ensure that it does not exceed the available memory of your application.
- Now that the size of the image is known, we can decide whether to load the entire image into memory or a compressed version into memory. Here are a few factors to consider:
- Estimate how much memory it will take to load the entire image.
- How much memory are you willing to provide in order to load this image?
- The actual size of the control used to display this image.
- Screen size and resolution of the current device.
- For example, if your ImageView is only 128×96 pixels, just to display a thumbnail, it’s not worth loading a 2048×1536 pixel image into memory.
6.1 Compress an Image
- How can I compress an image?
- This is done by setting the value of inSampleSize in bitmapFactory. Options.
- If you have a 2048×1536 pixel image, set inSampleSize to 4 to compress the image to 512×384 pixels.
- Loading the image used to take up 13M of memory, but when compressed, it takes up 0.75m (assuming the image is ARGB_8888, or 4 bytes per pixel).
- The following method calculates the appropriate inSampleSize value based on the width and height passed in:
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, Final int height = options.outheight; // Final int height = options.outheight; final int width = options.outWidth; intinSampleSize = 1; if(height > reqHeight | | width > reqWidth) {/ / calculate the actual wide high and the target width ratio of final int heightRatio = math.h round ((float) height / (float) reqHeight); final int widthRatio = Math.round((float) width / (float) reqWidth); // Select the ratio of width and high school as the minimuminSampleSize, so that the final image width and height // will be greater than or equal to the target width and height.inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } return inSampleSize; } Copy the code
6.2 Setting the BitmapFactory.Options property
- The general steps are as follows
- To parse an image, set bitmapFactory. Options to True to inJustDecodeBounds. Note that this is the core, the parsed image does not generate a Bitmap (that is, it does not allocate memory controls to it), but merely gets its width and height properties.
- Bitmapfactory.options are then passed to the calculateInSampleSize method with the desired width and height to get the appropriate inSampleSize value. This step compresses the image.
- After parsing the image again, use the newly acquired inSampleSize value and set to False to inJustDecodeBounds to get the compressed image. At this point, the bitmap object is officially created. Since it has been compressed previously, you will notice that the amount of memory used at this point is very small.
- Specific implementation code
Public static Bitmap decodeSampledBitmapFromResource (Resources res, int resId, int reqWidth, int reqHeight) {/ / resolution will be the first timeinJustDecodeBounds set totrueFinal bitmapFactory.options Options = new bitmapFactory.options (); options.inJustDecodeBounds =true; BitmapFactory.decodeResource(res, resId, options); // Call the method defined above to calculateinSampleSize value options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Use the obtainedinSampleSize value again resolution picture options. The inJustDecodeBounds =false; return BitmapFactory.decodeResource(res, resId, options); } Copy the code
- Consider: What is the inJustDecodeBounds parameter for?
- If set to true, the decode function does not generate a bitmap, but simply fills the option object with the image-related parameters, so that we can retrieve the image parameters without generating a bitmap.
- Why set the inJustDecodeBounds property twice?
- First time: Set to true means that the decode function does not generate a bitmap object, but just fills the image-related parameters into the Option object, so that we can get the parameters of the image without generating a bitmap.
- Second: Setting inJustDecodeBounds to false generates a Bitmap when decode is called again. The bitmap has been compressed so much that loading into memory will not result in OOM.
6.3 Setting a BitMap to the View
- Compress any image into a 100 x 100 thumbnail and display it in ImageView.
mImageView.setImageBitmap( decodeSampledBitmapFromResource(getResources(), R.id.ycimage, 100, 100)); Copy the code
The other is introduced
01. About blog summary links
- 1. Tech blog round-up
- 2. Open source project summary
- 3. Life Blog Summary
- 4. Himalayan audio summary
- 5. Other summaries
02. About my blog
- Github:github.com/yangchong21…
- Zhihu: www.zhihu.com/people/yczb…
- Jane: www.jianshu.com/u/b7b2c6ed9…
- csdn:my.csdn.net/m0_37700275
- The Himalayan listening: www.ximalaya.com/zhubo/71989…
- Source: China my.oschina.net/zbj1618/blo…
- Soak in the days of online: www.jcodecraeer.com/member/cont.
- Email address: [email protected]
- Blog: ali cloud yq.aliyun.com/users/artic… 239.headeruserinfo.3.dT4bcV
- Segmentfault headline: segmentfault.com/u/xiangjian…
- The Denver nuggets: juejin. Cn/user / 197877…