1.为什么显示图片的问题很棘手?

手机显示一张800万像素的图片(现在主流的手机像素都是在800万像素以上),大约需要32M的内存,而32M内存刚好是Android系统分配给应用的最大内存限制数目,当然有的手机分配是的16M,有的甚至只有8M,这个根据手机的总共RAM与版本有一定得联系,所以如果手机中的应用打开一张这样的图片的话,基本上都会遇到内存泄露的问题,导致的内存严重不足,一般情况下将会导致应用被强制退出

以Galaxy Nexus 为例,前后置的相机的像素是500W,其分辨率是2592*1936 如果位图使用的ARGB_8888(在Android 2.3以上版本一般默认设置是这种图片的格式) 加载该位图将大概占用19M 的内存(2592*1936*4 byte),因此程序会很快耗尽内存为每个应用分配的内存,从而导致程序员崩溃

即使应用程序不一定非得显示一张500W像素的图片,但是当在ListView,GridView中显示大量的图片,并且图片没有来得及回收的情况下,同事所占用的内存将是每张图片的总和,如果不对图片进行处理,将一样的会出现程序员因内存不足而强制退出

2.如何解决图片显示导致内存溢出的问题?

要解决图片显示导致内存的溢出,得考虑5个问题:

2.1如何高效的加载大位图

2.2如何在非UI线程中处理位图

2.3如何对位图进行缓存

2.4如何管理位图内存

2.5如何在Ui中显示位图

3.如何高效加载大位图

3.1获取位置以及尺寸

使用BitmaoFactory对位图进行解码的时候,使用BitmapFactory.Options ,将Options的injusDecodeBounds设为true时,可以避免为位图分配内存,此时的BitmapFactory.decdeX将返回null,但是会为Options设置outWidth,outHeight,outMemiType值

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;

通过上述的代码你就可以在不为位图分配内存的情况下,获取位图的高与宽与位图的类型,之后在显示图片的时候,就可以通过获取的信息来判断是否需要对图片进行出来之后再显示,从未避免内存溢出的问题

3.2将缩小的图片加载到内存

如果仅仅需要对128*96的图片缩略图进行显示,而将一张原始大小为1024*768的图片加载到内存,就显得很不划算,因此对图片进行压缩之后再显示就很有必要了,因此对图片按照比例缩小再进行显示就显得很有必要了

通过设置Option.insampleSize来产生缩小之后的图片,例如Option.insampleSize=4,那么一张原始大小为2048*1536的位图来说,产生的新位图的大小约为512*384,将这么大的位图加载到内存却只需要0.75M 的内存,而原图片却需要大概12M的内存

具体程序实现如下,将injustDecodeBounds设置为ture获取到位图信息,然后再设置insampleSize的值,然后再将injustDecodeBounds设置为false,从而将新产生的位图加载到内存

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,int reqWidth, int reqHeight) {// First decode with inJustDecodeBounds=true to check dimensionsfinal BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeResource(res, resId, options);// Calculate inSampleSizeoptions.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);// Decode bitmap with inSampleSize setoptions.inJustDecodeBounds = false;return BitmapFactory.decodeResource(res, resId, options);
}

上述方法使用calculateInSampleSize方法实现如下:

public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {// Raw height and width of imagefinal int height = options.outHeight;final int width = options.outWidth;int inSampleSize = 1;if (height > reqHeight || width > reqWidth) {// Calculate ratios of height and width to requested height and widthfinal int heightRatio = Math.round((float) height / (float) reqHeight);final int widthRatio = Math.round((float) width / (float) reqWidth);// Choose the smallest ratio as inSampleSize value, this will guarantee// a final image with both dimensions larger than or equal to the// requested height and width.inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;}return inSampleSize;
}

需要注意的是上述返回的InSampleSize的值最好是2的N次幂

综上所述有了上述的方法,我们就可以在程序中,加载任意大小的图片,而不用担心内存溢出的问题,例如下面的代码将会把图片设置成100*100像素的缩略图:

mImageView.setImageBitmap(decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));

转载自:http://yhz61010.iteye.com/blog/1848337

Android 高效现实图片问题相关推荐

  1. Android高效异步图片加载框架

    概述 Android高效异步图片加载框架:一个高效的异步加载显示的图片加载框架,同时具备图片压缩,缓存机制等特性. 详细 代码下载:http://www.demodashi.com/demo/1214 ...

  2. Android高效旋转图片的方式

    文章目录 背景 renderscript方式的优缺点 代码 结束 背景 在项目开发中涉及到比较多的图片处理,如摄像头预览图片的旋转,送入人脸识别sdk的图片数据,上传到后台识别记录的抓拍图片等等,以前 ...

  3. Android 高效显示Bitmap图片

    Android 高效显示Bitmap图片 本文会介绍一些处理与加载Bitmap对象的常用方法,这些技术能够使得程序的UI不会被阻塞,并且可以避免程序超出内存限制.如果我们不注意这些,Bitmap会迅速 ...

  4. Android 将ARGB图片转换为灰度图

    思路如下: 1.读取or照相,得到一张ARGB图片. 2.转化为bitmap类,并对其数据做如下操作: A通道保持不变,然后逐像素计算:X = 0.3×R+0.59×G+0.11×B,并使这个像素的值 ...

  5. Android 圆形/圆角图片的方法

    Android 圆形/圆角图片的方法 眼下网上有非常多圆角图片的实例,Github上也有一些成熟的项目.之前做项目,为了稳定高效都是选用Github上的项目直接用.但这样的结束也是Android开发必 ...

  6. Android高效加载大图、多图解决方案,有效避免程序内存溢出现象

    好久没有写博客了,今天就先写一个小的关于在Android中加载大图如何避免内存溢出的问题. 后面会写如何使用缓存技术的核心类,android.support.v4.util.LruCache来加载图片 ...

  7. android thumb大小,Android 设置thumb图片大小

    xml: android:thumb="@drawable/seekbar_thumb" seekbar_thumb.xml: 修改为: private int seekWidth ...

  8. Android设计一个图片加载框架

    本文不是具体编码去实现一个图片加载的框架,而是从理论上来讲解设计一个图片加载框架的注意事项和涉及的知识点,提供一个思路,或者帮助童鞋们应付面试.目前Android 发展至今优秀的图片加载框架太多,例如 ...

  9. linux 浏览器源码下载,Android开发:图片浏览器源码

    Android 图片浏览器源码,是你学习Android很好的例子,希望对你的学习有帮助. main.xml android:layout_width="fill_parent" a ...

最新文章

  1. matlab 在图片上绘制热力图_python可视化之seaborn——热力图
  2. 【Android 系统开发】 Android 系统启动流程简介
  3. php byte转 宽字符,C++宽字符与普通字符的转换实例详解
  4. 设计模式解析笔记之Adapter模式
  5. 信号的采样与插值重建(包含matlab)
  6. 如何使用示例从Java中的类路径加载资源
  7. 【机器学习】 - keras学习 - 图片生成器ImageDataGenerator
  8. 十步轻松搞定IIS+PHP环境搭建
  9. 【0201】用户登录界面设计
  10. 9. 机器人正运动学---修改DH参数
  11. robots.txt漏洞
  12. JavaWeb-EL表达式、JSTL标签
  13. 【论文翻译】nuPlan: A closed-loop ML-based planning benchmark for autonomous vehicles
  14. 更改oracle监听默认端口
  15. 第十六章 时间序列数据分析基本概念
  16. 数据太大,记事本打不开怎么办?
  17. UE ReplayKit for iOS插件使用
  18. word 2003 视频教程
  19. “超融合”元年,你准备好了吗?
  20. SAP 维护SD价格的探讨

热门文章

  1. Guava Cache 如何防止缓存击穿
  2. 2.Windchill -- 系统简单介绍
  3. 阿里云下配置keepalive
  4. 字符识别系统仿真–Matlab GUI实现
  5. 经典的python入门书籍,每位初学者必备书籍
  6. 页面布局-----display:flex详解
  7. 未来的5年我想成为什么样的人
  8. 记trace目录下不停增长cdump文件,trc文件中有oer 8102.2错误
  9. java+ssm大学生综合素质测评系统
  10. emqtt服务器 java_手把手教你EMQTT 服务器端