Android中的多媒体显示之图片缩放

时间:2022-12-22 20:34:29

 

一:图片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);
	}
}


出现问题:

Android中的多媒体显示之图片缩放

解析问题:

一:图片明明就: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

 

此时图片能正确显示:

 

Android中的多媒体显示之图片缩放

 

 

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

Android中的多媒体显示之图片缩放