当前位置: 代码迷 >> Android >> Android中的多媒体展示之图片缩放
  详细解决方案

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

热度:37   发布时间:2016-04-28 07:56:53.0
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

  相关解决方案