Android学习笔记:如何高效显示图片,避免内存溢出 和 ImageView无法显示大尺寸的图片
因为手机的内存资源是有限的,每个app可使用的内存是受限的。而现在采用高分辨率拍的照片往往很大。如果加载时不注意方法,很有可能会引起java.lang.OutofMemoryError: bitmap size exceeds VM budget. 异常而导致app奔溃退出。
另外ImageView支持的图片大小也是受限制的,比如整个App虽然只放一张图片,该图片大小也没超过整个app的内存上限。但该图片大小超过了ImageView的最大值,这也是有问题的。这时需要采取方法,在加载图片时缩小加载图片的大小。具体的策略看下面的介绍。
在真正创建和加载(需要实际耗费内存)一个图片对象时,我们可以先获取图像的大小信息。这里我们可以用到BitmapFactory.Options这个类。BitmapFactory.Options这个类,有一个字段叫做 inJustDecodeBounds 。SDK中对这个成员的说明是这样的:
“If set to true, the decoder will return null (no bitmap), but the out... fields will still be set, allowing the caller to query the bitmap without having to allocate the memory for its pixels.”
也就是说,如果我们把它设为true,那么BitmapFactory.decodeFile(String path, Options opt)并不会真的返回一个Bitmap给你,但它会把它的宽,高等基本信息取回来给你,这样就不会实际分配图片所需的内存。代码例子如下:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.drawable.pic1, options);
String text = "imageHeight:" + options.outHeight + ",imageWidth:"
+ options.outWidth + ",imageType:" + options.outMimeType;
Toast.makeText(this, text, Toast.LENGTH_LONG).show();
知道了图片的大小后,就可以考虑是将整个完整的图片加载到内存中,或是将缩小版加载到内存中。因为手机屏幕本身大小就那么大,没必要将原尺寸的图片加载进去。比如如果屏幕的大小为128x96,则将大小为1024x76的图片加载进去就没有意义。
为了告诉解码器将图片压缩后加载到内存中,需要设置BitmapFactory.Options对象的 inSampleSize 属性。比如,一张2048*1536的图片,如果设置inSampleSize的值为4. 缩小后图片的尺寸变为 512x384。占用的内存由原来的12M变为0.75M。下面的方法可以计算出一个图片应该设置的inSampleSize值:
public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// reqWidth、reqHeight是想要显示图片的大小,如屏幕的大小或ImageView控件的大小
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1; if (height > reqHeight || width > reqWidth) {
//说明图片的真实大小,大于需要显示的大小,则需要缩小图片
final int halfHeight = height / 2;
final int halfWidth = width / 2;
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
} return inSampleSize;
}
有了适当的inSampleSize值后,就可以真正的执行加载图片的操作了。代码如下:
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
options.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeResource(res, resId, options); ImageView imageView = (ImageView)findViewById(R.id.imageView1);
imageView.setImageBitmap(bitmap);
实际上对于大的图片,通过使用inSampleSize将图片变小后加载到内存中,只要不是变了非常小,不会影响视觉效果。但来的好处是显而意见的,会大大降低对内存的使用。一般对于大尺寸的照片(如用手机自身拍的),将inSampleSize设置为4一般不会影响视觉效果。
Android学习笔记:如何高效显示图片,避免内存溢出 和 ImageView无法显示大尺寸的图片的更多相关文章
- Android学习笔记进阶之在图片上涂鸦(能清屏)
Android学习笔记进阶之在图片上涂鸦(能清屏) 2013-11-19 10:52 117人阅读 评论(0) 收藏 举报 HandWritingActivity.java package xiaos ...
- Android学习笔记_51_转android 加载大图片防止内存溢出
首先来还原一下堆内存溢出的错误.首先在SD卡上放一张照片,分辨率为(3776 X 2520),大小为3.88MB,是我自己用相机拍的一张照片.应用的布局很简单,一个Button一个ImageView, ...
- 【转】 Pro Android学习笔记(七四):HTTP服务(8):使用后台线程AsyncTask
目录(?)[-] 5秒超时异常 AsyncTask 实现AsyncTask抽象类 对AsyncTask的调用 在哪里运行 其他重要method 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注 ...
- 【转】 Pro Android学习笔记(七五):HTTP服务(9):DownloadManager
目录(?)[-] 小例子 保存在哪里下载文件信息设置和读取 查看下载状态和取消下载 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件,转载须注明出处:http://blog.csd ...
- 【转】 Pro Android学习笔记(三三):Menu(4):Alternative菜单
目录(?)[-] 什么是Alternative menu替代菜单 小例子说明 Alternative menu代码 关于Category和规范代码写法 关于flags 多个匹配的itemId等参数 什 ...
- 【转】 Pro Android学习笔记(二二):用户界面和控制(10):自定义Adapter
目录(?)[-] 设计Adapter的布局 代码部分 Activity的代码 MyAdapter的代码数据源和构造函数 MyAdapter的代码实现自定义的adapter MyAdapter的代码继续 ...
- 【转】Pro Android学习笔记(十四):用户界面和控制(2):Text类控制
目录(?)[-] TextView 例子1在XML中设置autoLink属性 例子2在代码中设置autoLink属性 EditText AutoCompleteTextView MultiAutoCo ...
- 【转】Pro Android学习笔记(三):了解Android资源(上)
在Android开发中,资源包括文件或者值,它们和执行应用捆绑,无需在源代码中写死,因此我们可以改变或替换他们,而无需对应用重新编译. 了解资源构成 参考阅读Android学习笔记(三八):资源res ...
- Android学习笔记进阶16之BitmapShader
<1>简介 具体的看一下博文:Android学习笔记进阶15之Shader渲染 public BitmapShader(Bitmap bitmap,Shader.TileMode ti ...
随机推荐
- 模拟美萍加密狗--Rockey2虚拟狗(二)
按好了WDK,看了一天的DSF例子GenericHID,直接头大了,就能改个VID,PID让美萍识别成R2的狗.其他的什么各种描述符,根本无从下手,怪不得网上没有驱动模拟的加密狗,确实太复杂了,特别像 ...
- inlay检验标准
Inlay 检验标准 检验条件及要求 正常的 40W 日光灯下距离被检物 50cm,眼睛距离被检物 30cm,与被检物呈 45 度角,目视检 使用强光灯箱透视其内部结构 适用范围 Inlay 中料 检 ...
- cocos2d-x中的尺寸之二
接下来我们再做些坏事,比如给EGLView设置分辨率,代码如下: pEGLView->setDesignResolutionSize(240, 320, kResolutionExactFit) ...
- 实现最小宽度的几种方法及CSS Expression[转]
实现最小宽度的几种方法及CSS Expression[转] 实现最小宽度的几种方法:css表达式尽量不用 支持FF IE7 IE6 .test { background:blue; min-widt ...
- Dancing Stars on Me(判断正多边形)
Dancing Stars on Me Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Ot ...
- SQL Server调试常用参数
SQL Server 清除缓存: DBCC DROPCLEANBUFFERS 从缓冲池中删除所有清除缓冲区. DBCC FREEPROCCACHE 从过程缓存中删除所有元素. DBCC FREESYS ...
- 记载abp中Dbcontext的疑问
q:abp中httpcontext如何在一次请求中保证获取的是相同的实例. 大牛的原话: LifestylePerWebRequest does not works good with async. ...
- 玩转Bootstarp(连载)
一.Bootstarp是什么? 简单.灵活的用于搭建WEB页面的HTML.CSS.JS的工具集 (基于HTML5和CSS3) 总结:简洁强大的前端开发框架,可以让WEB开发更迅速.更简单 二.如何使用 ...
- 循环训练(for的嵌套、while、do while)以及异常处理
For的嵌套 练习一: 练习二: 练习三: 练习四: while的使用方法: 示例一: 示例二: 示例三: while的练习题: do while的使用示例: 异常处理示例: try catch ...
- html相关介绍
HTML(超文本标记语言) 超文本标记语言,即HTML(Hypertext Markup Language),是用于描述网页文档的一种标记语言 XHTML1.0 可扩展超文本置标语言(eXtensi ...