Android Developers:高效的加载大的位图
来源:互联网 发布:淘宝网店店铺装修 编辑:程序博客网 时间:2024/06/05 17:09
图片以各种各样的形式展现。在许多情况下,它比一个典型应用程序用户界面(UI)的要求更大。例如,系统的Gallery应用程序显示使用Android设备的照相机拍摄的照片,它是典型的比你设备屏幕的密度大很多。
考虑到你在内存限制的条件下工作, 理想的情况下,你仅仅需要加载一个低分辨率的版本到内存中。这低分辨率的版本应该和显示它的UI组件的大小符合。一个高分辨率的图片不会有任何可见的好处,但是一直消耗宝贵的内存和由于额外的缩放产生的附加的性能损失。这节课程将引导你,通过加载一个更小的子样品版本到内存中,在不超出每个程序内存显示的情况下编码大位图。
获取位图的尺寸和类型
BitmapFactory类提供了几个编码方法(decodeByteArray(),decodeFile(),decodeResource()等)用于从各种源创建一个位图。在你的图片数据源的基础上选择最合适的编码方式。这些方法为了构造位图试图分配内存,因此能很容易产生OutOfMemory异常。每一种编码方式都有额外的特性,你可以通过BitmapFactory.Option类指定编码选项。设置inJustDecodeBounds属性为true,在编码的时候避免内存分配,位图对象返回null但是设置了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;为了避免java.lang.OutOfMemory异常,在编码之前检查位图的尺寸,除非你绝对的确信提供给你的图片的数据大小在可用的内存中充分的合适。
向内存中加载一个缩小版本
现在图片的尺寸已经已知,它用来决定是向内存中加载整张图片还是加载一个子版本代替。下面有几个你需要考虑的因素:- 估算加载整张图片的内存消耗。
- 根据应用程序其他的内存需求,你愿意为加载这张图片所分配的内存。
- 加载图片的ImageVeiw或UI控件的尺寸。
- 当前设备的屏幕大小和尺寸。
告诉你的编码器对图片进行采样,向内存中加载一个小版本的图片,在BitmapFactory.Option对象中设置inSampleSize属性为true。例如,一张使用inSampleSize为4属性编码的分辨率为2048*1536的图片,最终产生一张大约512*384的位图。向内存中加载它使用0.75MB而不是加载整张图片(假定使用ARGB_8888编码位图)的12MB。下面的方法是一个基于目标的宽和高计算抽样的大小:
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) { if (width > height) { inSampleSize = Math.round((float)height / (float)reqHeight); } else { inSampleSize = Math.round((float)width / (float)reqWidth); } } return inSampleSize;}注意:使用2的幂作为inSampleSize的值使得编码器更快更高效。然而,你打算在内存和硬盘中缓存这个重置大小的版本,那么为了节省空间编码最适合的图片尺寸是值得的。
使用这样方法,第一次编码将inJustDecodeBounds设置为true,获取options。然后将inJustDecodeBounds设置为false,并传入options和新的inSampleSize值重新编码。
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);}这种方法使在100*100像素的ImageView缩略图中加载任意大小的图片变得很容易,如下示例代码所示:
mImageView.setImageBitmap( decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));
你可以使用相似的流程从其它的源中编码位图,根据需要通过替换相应的BitmapFactory.decode.*方法即可。
文档目录:Developers/Training/Advanced Tranining/Displaying Bitmaps Efficiently/Loading Large Bitmaps Efficiently
- Android Developers:高效的加载大的位图
- Android---高效的加载大位图
- Android---高效的加载大位图
- 高效的加载大Bitmap(位图)
- 高效的显示位图(二):高效加载大…
- 高效加载大位图
- Loading Large Bitmaps Efficiently-高效的加载大位图
- Loading Large Bitmaps Efficiently 高效的加载大尺寸位图
- 连载 1 - 深入讨论 Android 关于高效显示图片的问题 - 如何高效的加载大位图
- 【Android Training - 09】高效地显示Bitmap图片 [ Lesson 1 - 有效率地加载大尺寸的位图]
- 【Google官方教程】第一课:高效的加载大Bitmap(位图)
- 高效地显示Bitmap图片 1 - 有效率地加载大尺寸的位图
- 【Android Developers Training】 55. 序言:高效显示位图
- Android官方开发文档Training系列课程中文版:高效显示位图之加载大位图
- 高效地加载大Bitmap(位图)
- 高效地加载大Bitmap(位图)
- 高效加载大的图片
- 创建带有动画的APP 之 高效的显示位图:高效的载入大的位图
- .NET导出Excel遇到的80070005错误的解决方法
- 分布式系统
- 经得起风雨,却经不起平凡
- 数据结构---->绪论
- 数据结构学习之循环队列c++实现
- Android Developers:高效的加载大的位图
- Debian 安装 VMware tools
- gluLookAt
- ORACLE DATE和TIMESTAMP数据类型的比较【转载】
- 高效的JS 拼接字符串
- CF 214D
- Flex中采用Flex-config.xml进行命令行的编译
- 关于 Android SDK r20.0.1 更新后,Hierarchical Parent 必须填写的解决办法
- mysql 主从 配置 步骤 方法