Efficiently load large-size bitmaps (Loading Large Bitmaps efficiently)
The pictures have different shapes and sizes. In most cases, their actual size is much larger than what needs to be presented. For example, the system's Gallery program displays pictures that you take with your device's camera , but those images usually have a much higher resolution than the screen resolution of your device.
Given that the program is working in limited memory, ideally you only need to load a low-resolution version in memory. This low-resolution version should match the size of your UI to make it easier to display. A high-resolution picture does not provide any visible benefits, but it consumes valuable (precious) memory resources and can cause (incurs) additional efficiency problems when the picture is quickly sliding.
This lesson will show you how to decoding large bitmapsby loading a smaller version of the image into memory toavoid exceeding the program's memory limit.
Reading the dimensions and types of bitmaps (read Bitmap Dimensions and type)
Bitmapfactoryclass provides a number ofDecodethe method(Decodebytearray (), DecodeFile (), Decoderesource (), etc.)used to create one from different resources.Bitmap.Choose the right one based on your image data source .DecodeMethod. Those methods attempt to allocate memory when constructing bitmaps, so it is easy to causeOutOfMemorythe exception. Every kindDecodemethods are provided through thebitmapfactory.optionsto set some additional tags to specifyDecode's options. set the Injustdecodebounds property to true to avoid memory allocations when decoding, and it returns a null bitmap, but outwidth, Outheight and Outmimetype can still be obtained. This technique allows you to prioritize the size and type of images before you construct bitmap.
Bitmapfactory.options Options = new Bitmapfactory.options ();
Options.injustdecodebounds = true;
Bitmapfactory.decoderesource (Getresources (), r.id.myimage, options);
int imagewidth = Options.outwidth;
String imageType = Options.outmimetype;
To avoid java.lang.OutOfMemory anomalies, we need to Check the size of the image before actually decode it, Unless you are sure that this data source provides an accurate picture and does not result in excessive memory consumption.
Load a scaled-down version to memory (load a scaled down version into memories)
With the above steps we already know the size of the image, which can be used to decide whether the entire image should be loaded into memory or a scaled down version. Here are some factors to consider:
Evaluate the memory required to load the full picture.
The program involves other memory requirements when loading this image.
The size of the component that renders the picture.
Screen size and screen density of the current device.
For example, if you put a picture that is 1024x768 pixel to ImageView for 128*96 Pixel Thumbnail, there is no need to load the entire picture into memory.
To tellDecoderto load a lower version of the image into memory, need to be in yourbitmapfactory.optionsset ininsamplesizeto betrue. For example,a resolution of2048x1536the picture, if setinsamplesizeto be4, it will produce an approximate512x384of theBitmap. Loading this small picture is just about using0.75MB, if it's loading the full map, then it's probably going to cost12MB (the premise isBitmapthe configuration isargb_8888). Here's a section based on the target image size.Samplethe size of the pictureSample Code:
public static int Calculateinsamplesize (
Bitmapfactory.options Options, int reqwidth, int reqheight) {
Raw height and width of image
Final int height = options.outheight;
Final int width = options.outwidth;
int insamplesize = 1;
if (Height > Reqheight | | width > reqwidth) {
Final int halfheight = HEIGHT/2;
Final int halfwidth = WIDTH/2;
Calculate the largest insamplesize value is a power of 2 and keeps both
Height and width larger than the requested height and width.
while ((halfheight/insamplesize) > Reqheight
&& (halfwidth/insamplesize) > Reqwidth) {
Insamplesize *= 2;
}
}
return insamplesize;
}
Note: setting the power of insamplesize to 2 is because decoder will eventually be on a non- 2 The number of powers to be processed downward, obtaining the number closest to the power of 2 . Refer to the insamplesize documentation for details.
To use this method, you first need to set injustdecodebounds to true, Pass the options value, and then use the insamplesize value and set injustdecodebounds to false to re - Decode again.
public static Bitmap Decodesampledbitmapfromresource (Resources res, int resId,
int reqwidth, int reqheight) {
First decode with injustdecodebounds=true to check dimensions
Final Bitmapfactory.options Options = new Bitmapfactory.options ();
Options.injustdecodebounds = true;
Bitmapfactory.decoderesource (res, resId, options);
Calculate insamplesize
Options.insamplesize = calculateinsamplesize (options, Reqwidth, reqheight);
Decode Bitmap with Insamplesize set
Options.injustdecodebounds = false;
Return Bitmapfactory.decoderesource (res, resId, options);
}
Using this method, you can simply load an image of any size and display it as a thumbnail of the 100*100 pixel . As shown in the following illustration :
Mimageview.setimagebitmap (
Decodesampledbitmapfromresource (Getresources (), R.id.myimage, 100, 100));
You can write a similar method to decode bitmap from other data sources by replacing the appropriate bitmapfactory.decode* method.
Efficiently load large-size bitmaps (Loading Large Bitmaps efficiently)