一:圖片OOM異常:
代碼示例:
[java]
public class MainActivity extends Activity {
private ImageView iv_imageView;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv_imageView = (ImageView) findViewById(R.id.Iv_imageView);
}
public void load(View view){
Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/1.jpg");
iv_imageView.setImageBitmap(bitmap);
}
}
出現問題:
解析問題:
一:圖片明明就:1.37MB(1,444,582字節),為什麼vm為16MB還會報錯-->OOM?
1.圖片要想被加載到內存中顯示,在內在中是以數組的方式保存的,用數組表示圖片中的每一個像素,
2.這個圖片雖然只有1.37MB,但其分辨率為:2592*1944=5038848,即在內存中要表示這麼多個點!
3.每個點都是有顏色的,RGB,所以每表示一個顏色,至少需要3個Byte來表示!
4.圖片支持都有透明度的,圖片的每個點都有一個參數&(0-255),1個字節,所以要表示一個點,需要四個Byte!
5.5038848*4=20155392Byte ---> 20155392/1024=19683KB ---> 19638/1024=19.2216796875MB,即要將那個1.37MB的圖片表示在計算機內存中,需要19.2216796875MB的內存,大於VM Heap:16MB,故OOM!
6.所以圖片要顯示在手機內存中要進行相應的處理,不能直接顯示原圖!一般所建的模擬器屏幕也就320*480,即只能表示這麼多的像素。所以原圖的每個點不能完全顯示在手機的屏幕上!所以將圖片依據手機屏幕做相應的縮放
二:對圖片進行縮放的算法:
1.獲取手機屏幕的分辨率:寬,高:320*480
2.獲取圖片的寬高信息:2592*1944
3.計算圖片的縮放比例:
水平方向:2592/320=8.1
豎直方向:1944/480=4.05
4.確定顯示的縮放比例:取大的一方(否則顯示不全!)9.1
5.縮放完畢後,
詳細代碼:
[java]
public class MainActivity extends Activity {
private ImageView iv_imageView;
private int windowWidth;
private int windowHeight;
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv_imageView = (ImageView) findViewById(R.id.Iv_imageView);
//1.獲取手機屏幕的分辨率 寬高
Display display = getWindowManager().getDefaultDisplay();
windowWidth = display.getWidth();
windowHeight = display.getHeight();
System.out.println("屏幕的寬度:" + windowHeight);
System.out.println("屏幕的高度:" + windowHeight);
}
public void load(View view){
// Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/1.jpg");
// iv_imageView.setImageBitmap(bitmap);
Options opts = new Options();
//2.0設置解析器不去真正的解析這個位圖,而是解析這個圖片的out輸出信息(寬度,高度),不會為圖片的每個點申請內在空間
opts.inJustDecodeBounds = true;
//2.得到圖片的寬高信息
BitmapFactory.decodeFile("/sdcard/1.jpg",opts);
int picHeight = opts.outHeight;
int picWidth = opts.outWidth;
System.out.println("圖片的寬度:" + picWidth);
System.out.println("圖片的高度:" + picHeight);
//3.得到縮放比例
int scaleX = picWidth/windowWidth;
int scaleY = picHeight/windowHeight;
System.out.println("水平縮放比例:" + scaleX);
System.out.println("豎直縮放比例:" + scaleY);
//3.2. 確定縮放比例:
int scale = 1;
if(scaleX > scaleY && scaleY>1){
scale = scaleX;
}
if(scaleY > scaleX && scaleX>1){
scale = scaleY;
}
System.out.println("最終確定的縮放比例:" + scale);
//4.真正的解析這個圖片
opts.inJustDecodeBounds = false;
opts.inSampleSize = scale;
Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/1.jpg",opts);
iv_imageView.setImageBitmap(bitmap);
}
}
運行時log:
09-29 16:05:37.715: I/System.out(23786): 屏幕的寬度:480
09-29 16:05:37.715: I/System.out(23786): 屏幕的高度:480
09-29 16:07:12.085: I/System.out(23786): 圖片的寬度:2592
09-29 16:07:12.085: I/System.out(23786): 圖片的高度:1944
09-29 16:07:12.105: I/System.out(23786): 水平縮放比例:8
09-29 16:07:12.115: I/System.out(23786): 豎直縮放比例:4
09-29 16:07:12.115: I/System.out(23786): 最終確定的縮放比例:8
09-29 16:17:26.475: I/System.out(23786): 屏幕的寬度:320
09-29 16:17:26.475: I/System.out(23786): 屏幕的高度:320
09-29 16:17:33.336: I/System.out(23786): 圖片的寬度:1280
09-29 16:17:33.336: I/System.out(23786): 圖片的高度:1024
09-29 16:17:33.345: I/System.out(23786): 水平縮放比例:2
09-29 16:17:33.345: I/System.out(23786): 豎直縮放比例:3
09-29 16:17:33.345: I/System.out(23786): 最終確定的縮放比例:3