当前位置:操作系统 > 安卓/Android >>

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

一:图片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
 
补充:移动开发 , Android ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,