更有效率的加载大图片
2016-07-10 16:41
218 查看
按指定的大小得到图片防止OOM
本文结构:1.如何得到图片bitmap的尺寸与类型
2.如何将图片缩小后加载在内存中
原文连接:https://developer.android.com/training/displaying-bitmaps/load-bitmap.html
在开发中,我们所用到的图片各种各样,也来自不同的地方。比如手机上原装的相册管理器,里面的经过照相机所拍摄的图片就远远超过了对屏幕的展示要求,同时对图片不加以处理并直接使用,再结合现在设备的像素,我们很容易就会OOM,程序直接崩溃。同时过大的尺寸还会导致大量流量和时间去加载图片,使得用户的体验感糟糕到极致!
在不大的屏幕控件上,展示过于高清的图片对你的程序没有一点好处。所以在使用前我们必须经过相应的处理,保证程序的流畅执行是关键!
如何得到图片bitmap的尺寸与类型
针对不同数据源的图片,BitmapFactory为我们提供了各种各样生成Bitmap的方法,这些方法都在生成bitmap的同时进行内存的分配,因此也很容易导致OOM问题的发生。而BitmapFactory在生成Bitmap的同时也会提供一个如图所示的参数— BitmapFactory.Options类。
设置options中的inJustDecodeBounds属性为true,可以避免内存的分配。同时BitmapFactory会返回一个null的值。但同时,options的 outWidth, outHeight outMimeType属性都会分别被赋值,得到目标图片的大小尺寸和类型。
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;
如何将图片缩小后加载在内存中
OK,得到了我们的目标图片的大小,我们怎样进行图片的压缩得到我们想要的尺寸呢?继续参看BitmapFactory.Options~~
合理的设置inSampleSize参数可以得到缩小化的图片,比如inSampleSize =4可以将图片的长宽均压缩为原来的1/4.使其适应我们的屏幕控件。
那怎么得到这个合理的inSampleSize值呢??
public static int calculateInSampleSize( BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image 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; // Calculate the largest inSampleSize value that is a power of 2 and keeps both // height and width larger than the requested height and width. while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) { inSampleSize *= 2; } } return inSampleSize; }
我们可以通过制定要求的尺寸,再不断比较图片的现有尺寸是否满足,不满足则以2的倍数递增,直到满足最大尺寸要求为止。这样我们就可以得到满足实际需要的图片的大小参数!!
接下来吧这个参数设置给options,并通过BitmapFactory重新加载一次图片,记得要把inJustDecodeBounds的属性改回为false.
这样我们就可以得到需要的图片啦。同时合适的尺寸也不会影响视觉效果并可以更快更流畅的加载。
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) { // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(res, resId, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; return BitmapFactory.decodeResource(res, resId, options); }
远离OOM ,从你我做起~~
相关文章推荐
- Android之获取手机上的图片和视频缩略图thumbnails
- android wifi 无线调试
- 基于 Linux 的智能手机 Librem 5 开启预售
- 5 个可以满足你的生产力、沟通和娱乐需求的开源手机应用
- 每日安全资讯:哪些属于App违法违规收集使用个人信息?
- 每日安全资讯:命案侦破过程揭示 Google 能够跟踪全世界的手机
- 【DevOps】为什么我们永远疲于奔命?
- 网络管理之IP地址篇
- IE7降低内存和降低CPU的几个技巧
- 文件的读出 编辑 管理
- 手机4大隐藏功能及使用必知常识第1/2页
- 如何高效的使用内存
- DOS下内存的配置
- XP/win2003下发现1G的内存比512M还慢的解决方法
- SQL Server 2008 R2 应用及多服务器管理
- PowerShell实现动态获取当前脚本运行时消耗的内存
- C#实现把dgv里的数据完整的复制到一张内存表的方法
- SQL语句实现查询SQL Server内存使用状况
- Android改变手机屏幕朝向的方法