The main content of this article from Android Doc, I translated and done some processing, English good friends can also directly read the original.
Http://developer.android.com/training/displaying-bitmaps/index.html
Load large pictures efficiently
We often use a lot of pictures when we write Android programs, and different pictures always have different shapes and sizes, but in most cases, these pictures are larger than the size we need for our programs. For example, most of the pictures displayed in the system picture library were taken with the mobile phone camera, and the resolution of these images is much higher than the resolution of our mobile screen. You should know that we write the application has a certain memory limit, the program occupies too much memory can easily appear oom (outofmemory) exception. We can see in the following code how much memory is available for each application.
int maxmemory = (int) (Runtime.getruntime
(). MaxMemory ()/1024);
LOG.D ("TAG", "Max memory is" + MaxMemory + "KB");
So when you show high-resolution pictures, it's best to compress the pictures first. The size of the compressed picture should be similar to the size of the control used to display it, showing an oversized picture on a small imageview does not bring any visual benefit, but it takes up quite a lot of our valuable memory and can have a negative impact on performance. Let's take a look at how to compress a large picture properly so that it can be displayed at the best size and prevent Oom from appearing.
Bitmapfactory This class provides multiple parsing methods (Decodebytearray, DecodeFile, Decoderesource, etc.) for creating bitmap objects, we should choose the appropriate method based on the source of the image. For example, the image in SD card can use the DecodeFile method, the picture on the network can use the Decodestream method, the picture in the resource file can use Decoderesource method. These methods will attempt to allocate memory for the bitmap that have been built, and this can easily cause oom to appear. For this reason, each parsing method provides an optional bitmapfactory.options parameter that sets the Injustdecodebounds property of this parameter to true to prevent the parsing method from allocating memory for the bitmap. The return value is no longer a bitmap object, but null. Although the bitmap is null, the Outwidth, Outheight, and Outmimetype properties of the bitmapfactory.options will be assigned. This technique allows us to get the long width and mime type of the picture before loading the picture to compress the picture according to the situation. As shown in the following code:
Bitmapfactory.options Options = new Bitmapfactory.options ();
Options.injustdecodebounds = true;
Bitmapfactory.decoderesource (Getresources (), r.id.myimage, options);
int imageheight = options.outheight;
int imagewidth = options.outwidth;
String imagetype = Options.outmimetype;
To avoid oom exceptions, it's a good idea to check the size of each picture first, unless you trust the source of the image to ensure that it doesn't exceed the available memory of your program.
Now that the size of the picture is known, we can decide whether to load the entire picture into memory or load a compressed version of the picture into memory. Here are a couple of factors that we need to consider:
Estimate the amount of memory that is required to load the entire picture.
How much memory would you like to load in this picture?
The actual size of the control used to display this picture.
Screen size and resolution of the current device.
For example, your ImageView only 128*96 pixel size, just to show a thumbnail, at this time, a picture of 1024*768 pixel completely loaded into memory is obviously not worth it.
So how do we compress a picture? This can be achieved by setting the value of the insamplesize in the bitmapfactory.options. For example, we have a 2048*1536 pixel picture, the Insamplesize value is set to 4, you can compress this picture into 512*384 pixels. Originally loaded this picture needs to occupy 13M of memory, compressed only need to occupy 0.75M (assuming the picture is the argb_8888 type, that is, each pixel occupies 4 bytes). The following method calculates the appropriate insamplesize value according to the width and height of the incoming:
public static int calculateinsamplesize
(bitmapfactory.options Options,
int reqwidth, int reqheight) {
// The height and width of the source picture
final int height = options.outheight;
Final int width = options.outwidth;
int insamplesize = 1;
if (Height > reqheight | | | width > reqwidth) {
//Calculate the ratio of the actual width and height of the goal to the
final int heightratio = Math.Round ((float) Height/(float) reqheight);
Final int widthRatio = Math.Round ((float) width/(float) reqwidth);
Choose width and high school minimum ratio as the value of insamplesize, so that the final picture width and height
//must be greater than or equal to the width and height of the target.
insamplesize = HeightRatio < widthRatio? heightratio:widthratio;
}
return insamplesize;
}