Restore Heap Memory overflow error
First, restore the heap memory overflow error. First put a photo on the SD card, the resolution is (3776 X 2520), the size of 3.88MB, is my own camera took a picture. The layout of the application is simple, a button is ImageView, and then in the usual way, use bitmapfactory to load a picture and use a imageview display.
The code is as follows:
Copy Code code as follows:
Btn_loadimage.setonclicklistener (New View.onclicklistener () {
@Override
public void OnClick (View v) {
Bitmap bitmap=bitmapfactory.decodefile ("/sdcard/a.jpg");
Iv_bigimage.setimagebitmap (bitmap);
}
}
When the button is clicked, the program will give an error and view the log as:
To analyze this error first, DALVIKVM (Android virtual machine) found that the required memory 38MB is greater than the application of heap memory 24MB, this time trying to use a soft load to load the data, We know that when there is not enough memory DALVIKVM will automatically gc (garbage Collection), probably cleaned up 55k of space out of 203 milliseconds, but the memory is not enough, so the last heap memory overflow error.
Analysis Heap Memory Overflow
Android system is mainly used for low-power mobile devices, so there are many restrictions on memory management, an application, the Android system lacks the capital to allocate the maximum 16MB (some models are 24MB) space as heap memory space, I use the simulator here debugging, This simulator is set to 24MB and can be found in Android Virtual Device Manager.
And the picture here is clearly only 3.88MB, far less than the Android for the application of the allocation of heap memory, and loaded into memory, why the need to consume about 38MB of memory?
As we all know, pictures are made up of a single point distribution (resolution), typically loading such data creates a two-dimensional array in memory, each of which represents a point, and the resolution of the image is 3776 * 2520, each of which is composed of ARGB colors, each of which is 4 byte, So the memory required to load this image into memory is:
3776 * 2520 * 4byte = 38062080byte
Approximately 38MB of memory is required to properly load this picture, which is the above error description requires 38MB of memory space, the size of a slight discrepancy, because the picture and some EXIF information needs to be stored, than only by the resolution calculation to be larger.
How to load large resolution pictures
Sometimes we do need to load some big-resolution pictures, but for mobile devices, even if the load can succeed so much memory is a waste (screen resolution limit), so you need to find ways to compress the picture at a certain rate, so that the resolution is reduced, so that does not require a large heap of memory space, You can also use the device screen resolution to display the picture. A Bitmapfactory.options object is used here, which is described below.
Bitmapfactory.options is an internal class of bitmapfactory that is used primarily to set up some information for storing bitmapfactory loading pictures. The following are the attributes you need to use in options:
Injustdecodebounds: If set to true, the pixel array of the picture is not loaded into memory, and only some extra data is loaded into the options.
Outheight: The height of the picture.
Outwidth: The width of the picture.
Insamplesize: If set, the picture will be loaded based on this sample rate and cannot be set to a number less than 1. For example, set to 4, the resolution width and high will be the original 1/4, this time the overall memory will be the original 1/16.
Sample Demo
Here is a simple demo to demonstrate the content mentioned above, the comments in the code is more clear, here is no longer tired.
Copy Code code as follows:
Package cn.bgxt.loadbigimg;
Import Android.os.Bundle;
Import android.os.Environment;
Import android.app.Activity;
Import Android.graphics.Bitmap;
Import Android.graphics.BitmapFactory;
Import android.graphics.BitmapFactory.Options;
Import Android.view.Menu;
Import Android.view.View;
Import Android.view.WindowManager;
Import Android.widget.Button;
Import Android.widget.ImageView;
public class Mainactivity extends activity {
Private Button btn_loadimage;
Private ImageView Iv_bigimage;
@Override
protected void OnCreate (Bundle savedinstancestate) {
Super.oncreate (savedinstancestate);
Setcontentview (R.layout.activity_main);
Btn_loadimage = (Button) Findviewbyid (r.id.btn_loadimage);
Iv_bigimage = (ImageView) Findviewbyid (r.id.iv_bigimage);
Btn_loadimage.setonclicklistener (New View.onclicklistener () {
@Override
public void OnClick (View v) {
//Bitmap bitmap=bitmapfactory.decodefile ("/sdcard/a.jpg") ;
//Iv_ Bigimage.setimagebitmap (bitmap);
Bitmapfactory.options opts = new Options ();
//Do not read the array of pixels into memory, Read only the picture's information
Opts.injustdecodebounds = true;
Bitmapfactory.decodefile ("/sdcard/a.jpg", opts);
// Get the resolution of the picture from the options
int imageheight = Opts.outheight;
int imagewidth = Opts.outwidth;
Get the Android screen service
WindowManager wm = (WindowManager) getsystemservice (Window_service);
Get the resolution of the screen, GetHeight (), GetWidth has been discarded
You should use GetSize (), but you still use them for backward compatibility.
int windowheight = Wm.getdefaultdisplay (). GetHeight ();
int windowwidth = Wm.getdefaultdisplay (). GetWidth ();
Calculate sample Rate
int ScaleX = Imagewidth/windowwidth;
int ScaleY = Imageheight/windowheight;
int scale = 1;
The sampling rate is subject to the maximum direction.
if (ScaleX > ScaleY && scaleY >= 1) {
scale = ScaleX;
}
if (ScaleX < ScaleY && ScaleX >= 1) {
scale = ScaleY;
}
False indicates that the number of pixels in the image is read in memory, according to the set sampling rate
Opts.injustdecodebounds = false;
Sample Rate
Opts.insamplesize = scale;
Bitmap Bitmap = Bitmapfactory.decodefile ("/sdcard/a.jpg", opts);
Iv_bigimage.setimagebitmap (bitmap);
}
});
}
}
Effect Display:
Summarize
This explains how to load a large resolution picture into memory and use it. But generally better picture processing software, there will be image amplification function, if only to do this processing, simply the processing of the image amplification, will affect the display effect, the image reduction degree is not high. You will typically regain the resolution of the image of the magnified area as a group of pixels, and then process the load into memory for display.