高效的加载大尺寸图片

作者: rain 分类: 移动 发布时间: 2012-04-15 17:38 6 条评论

图片具有不同的形状和尺寸。通常情况下图片比设备的屏幕尺寸要大很多。例如,用Android系统的图库程序来显示手机摄像头拍摄的照片,这些照片的分辨率要比设备屏幕分辨率大很多。

考虑到程序可用的内存是有限的,所以您只要载入一个低分辨率的图片在内存中即可。这个低分辨率的图片应该和显示该图片的控件大小匹配。如果使用大的分辨率图片来显示在控件中并没有任何视觉提升,而且还要浪费很多内存和CPU性能。

这节内容演示了如何使用一个缩小后的图片来避免这些问题。

读取 Bitmap 的尺寸和类型

BitmapFactory
提供了一些解析图片的函数(decodeByteArray(), decodeFile(), decodeResource(), etc.)
来从不同的资源创建一个 Bitmap
根据您的图片所在的位置,选择不同的函数来创建图片。这些函数会申请需要的内存来创建图片,所以很容易导致 OutOfMemory 异常发生。
每个函数都有提供了解析图片的配置参数的重载函数,该参数为BitmapFactory.Options 类。
如果在解析图片的时候,设置该类的 inJustDecodeBounds 属性为 true
则不会申请内存并且返回 null 而不是一个Bitmap对象,同时还设置了
outWidth, outHeightoutMimeType 这些值。
这样您可以读取图片的尺寸和图片类型而不用载入该图片到内存中。

要避免 java.lang.OutOfMemory 异常,在载入图片前先检查下图片的尺寸。如果你非常确信图片来源提供的图片都是尺寸合适的,您可以不用检查。

载入缩小过的图片到内存中

现在知道了图片的尺寸大小,您可以根据该信息来决定要载入整个图片到内存中还是只载入该图片的一个缩略图。下面是一些需要考虑的因素:

  • 估计载入整个图片所需要的内存
  • 根据 程序运行情况能分配多少内存供图片使用
  • 用来显示该图片的ImageView或者其他控件的尺寸
  • 当前设备的屏幕尺寸和屏幕密度

例如,如果最终只显示一个128X96像素的缩略图,是完全没有必要把整个 1024×768 像素的图片数据都载入到内存中的。

通过设置BitmapFactory.Options参数的属性 inSampleSize
true 来载入一个图片的缩略图。例如,对于一个 2048×1536 分辨率的图片,使用
inSampleSize 的参数为4,会生成一个
512×384的缩略图。载入该缩略图到内存中只需要0.75MB,而整个图片需要12MB的内存(假设使用 ARGB_8888 格式的图片)。
下面的代码根据目标尺寸来计算图片的采样率参数(inSampleSize)的值:

注意: 对于参数 inSampleSize 而言,使用
2的平方值会提高解析效率。但是,如果您计划把缩略图缓存到内存或者磁盘中以便后续使用,通常还是建议使用尺寸匹配的缩略图来节省内存的消耗量。

要使用这种方式,先设置inJustDecodeBoundstrue
来得到图片的尺寸,然后在设置该值为 false同时设置计算好的 inSampleSize参数值来获取一个合适的缩略图。
:

通过上面的函数,可以载入任意大小的图片到一个ImageView 来显示。如下代码
显示一个100X100的缩略图:

本文出自 云在千峰,转载时请注明出处及相应链接。

本文永久链接: http://blog.chengyunfeng.com/?p=393

Ɣ回顶部