Android中的多媒體顯示之圖片縮放

 

一:圖片OOM異常:

代碼示例:

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字節),爲什麼vm16MB還會報錯-->OOM?

      1.圖片要想被加載到內存中顯示,在內在中是以數組的方式保存的,用數組表示圖片中的每一個像素,

      2.這個圖片雖然只有1.37MB,但其分辨率爲:2592*1944=5038848,即在內存中要表示這麼多個點!

3.每個點都是有顏色的,RGB,所以每表示一個顏色,至少需要3Byte來表示!

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.縮放完畢後,加載顯示圖片

 

詳細代碼:

 

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章