转 Android--加载大分辨率图片到内存

  在使用ImageView显示图片的时候,直接加载一个图片资源到内存中,经常会出现内存溢出的错误,这是因为有些图片的分辨率比较高,把它直接加载 到内存中之后,会导致堆内存溢出的问题。这篇博客就来讲解一下Android的堆内存以及如何在Android应用中加载一个高分辨率的图片。关于 ImageView不熟悉的朋友,可以看看之前的博客:Android--ImageView。

 

 

还原堆内存溢出的错误

  代码如下:

复制代码
1 btn_loadimage.setOnClickListener(new View.OnClickListener() {
2             
3  @Override 4 public void onClick(View v) { 5 Bitmap bitmap=BitmapFactory.decodeFile("/sdcard/a.jpg"); 6  iv_bigimage.setImageBitmap(bitmap); 7  } 8 }
复制代码

 

分析堆内存溢出

  我们都知道,图片是由一个一个点分布组成的(分辨率),通常加载这类数据都会在内存中创建一个二维数组,数组中的每一项代表一个点,而这个图片的分辨 率是3776 * 2520,每一点又是由ARGB色组成,每个色素占4个Byte,所以这张图片加载到内存中需要消耗的内存为:

  3776 * 2520 * 4byte = 38062080byte

 

如何加载大分辨率图片

  BitmapFactory.Options为BitmapFactory的一个内部类,它主要用于设定与存储BitmapFactory加载图片的一些信息。下面是Options中需要用到的属性:

    •   

 

示例Demo

 

复制代码
 1 package cn.bgxt.loadbigimg;
 2 
 3 import android.os.Bundle;  4 import android.os.Environment;  5 import android.app.Activity;  6 import android.graphics.Bitmap;  7 import android.graphics.BitmapFactory;  8 import android.graphics.BitmapFactory.Options;  9 import android.view.Menu; 10 import android.view.View; 11 import android.view.WindowManager; 12 import android.widget.Button; 13 import android.widget.ImageView; 14 15 public class MainActivity extends Activity { 16 private Button btn_loadimage; 17 private ImageView iv_bigimage; 18 19  @Override 20 protected void onCreate(Bundle savedInstanceState) { 21 super.onCreate(savedInstanceState); 22  setContentView(R.layout.activity_main); 23 24 btn_loadimage = (Button) findViewById(R.id.btn_loadimage); 25 iv_bigimage = (ImageView) findViewById(R.id.iv_bigimage); 26 27 btn_loadimage.setOnClickListener(new View.OnClickListener() { 28 29  @Override 30 public void onClick(View v) { 31 // Bitmap bitmap=BitmapFactory.decodeFile("/sdcard/a.jpg"); 32 // iv_bigimage.setImageBitmap(bitmap); 33 34 BitmapFactory.Options opts = new Options(); 35 // 不读取像素数组到内存中,仅读取图片的信息 36 opts.inJustDecodeBounds = true; 37 BitmapFactory.decodeFile("/sdcard/a.jpg", opts); 38 // 从Options中获取图片的分辨率 39 int imageHeight = opts.outHeight; 40 int imageWidth = opts.outWidth; 41 42 // 获取Android屏幕的服务 43 WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); 44 // 获取屏幕的分辨率,getHeight()、getWidth已经被废弃掉了 45 // 应该使用getSize(),但是这里为了向下兼容所以依然使用它们 46 int windowHeight = wm.getDefaultDisplay().getHeight(); 47 int windowWidth = wm.getDefaultDisplay().getWidth(); 48 49 // 计算采样率 50 int scaleX = imageWidth / windowWidth; 51 int scaleY = imageHeight / windowHeight; 52 int scale = 1; 53 // 采样率依照最大的方向为准 54 if (scaleX > scaleY && scaleY >= 1) { 55 scale = scaleX; 56  } 57 if (scaleX < scaleY && scaleX >= 1) { 58 scale = scaleY; 59  } 60 61 // false表示读取图片像素数组到内存中,依照设定的采样率 62 opts.inJustDecodeBounds = false; 63 // 采样率 64 opts.inSampleSize = scale; 65 Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/a.jpg", opts); 66  iv_bigimage.setImageBitmap(bitmap); 67 68  } 69  }); 70  } 71 }
复制代码

 

源码下载

 

  本篇博客到这里就讲解了如何加载一个大分辨率的图片到内存中并使用它。不过一般好一点的图片处理软件,都会有图片放大功能,如果仅做此处理,单纯的把 处理后的图片放大,会影响显示效果,图片还原度不高。一般会重新获取放大区域的图片的分辨率像素数组,然后重新处理加载到内存中进行显示。

转载于:https://www.cnblogs.com/deman/p/4260005.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值