官方推荐方法,如何有效率的加载大图Bitmap

翻译文章:https://developer.android.com/topic/performance/graphics/load-bitmap

本博主不是专业英语8级人士,此文章只是作为自己阅读文章的学习笔记,有不恰当的地方欢迎指正。

Loading Large Bitmaps Efficiently

★ 注意:目前有一些追求加载图片最佳体验的三方库。你们可以在自己的app中使用这些库加载图片已达到最优体验。我们推荐Glide库,这个库在加载和展示图片方面尽可能地快速和流畅。也有一些其他的流行图片加载库,例如Square出的Picasso和Facebook的Fresco。这些三方库都简化了在Android设备上与Bitmpap和其他类型图像相关的大部分复杂的工作。

图像有各种各样的形状和大小。在大多数情况下,它们都比应用UI需要的要大。例如,使用系统应用相册(Gallery)展示相机拍摄的照片,这些照片的分辨率基本上都远远大于设备屏幕的密度(density)。

考虑到应用只有有限的内存,理所当然的,我们只想在内存中加载低分辨率的图像即可。这张低分辨率的图像应该与展示它的UI控件的大小相匹配。高分辨率的图像并不能提供任何看得见的好处,更何况,它们还占据着宝贵的内存,并且会在快速滑动过程中导致额外的性能开销。

这篇文章将向你介绍在不超过应用内存限制的条件下,用加载更小的子样本的方式来解码一张大的Bitmap。

Read Bitmap Dimensions and Type

读取bitmap的尺寸和类型

类BitmapFactory提供了一系列的解码图片的方法(比如 decodeByteArray(),decodeFile(),decodeResource()),让我们可以根据不同的数据源来创建Bitmap对象。我们要基于图片的数据源来选取最适合的解码方法。这些方法都试图在构建Bitmap的时候为它们分配内存,因此很轻易的会导致OOM异常。

每一个类型的解码方法都会有一个额外的BitmapFactory.Options类型的参数让你指定附加的解码选项。在解码时,把inJustDecodeBounds这个属性设为true,这样的话,解码方法返回的bitmap对象为null,从而避免了分配内存;与此同时,bitmap的尺寸和类型信息也相应地保存到了传入的BitmapFactory.Options类型参数的outWidth,outHeight和outMimeTyp属性中。这项技术允许我们在不给bitmap分配内存的情况下,获取到bitmap的尺寸和类型的信息。

示例如下:

为了避免OOM异常,除非你完全信任数据源提供的图片并且确定不会占用太多内存,否则一定要在解码图片前检查图片尺寸。

Load a Scaled Down Version into Memory

加载一个小型样本到内存

现在我们知道了bitmap的尺寸,它们用来决定是否要将整张图片记载到内存中还是抽取一部分样本来代替。下面是一些我们需要考虑的因素:

          1、加载整张图片所需要耗费的内存;

          2、考虑到应用内存的限制,愿意为这张图片提供多少内存。

          3、将要展示图片的ImageView或者其他UI控件的大小

          4、当前设备的屏幕大小和密度(density)

例如,把一张1024x768的图片放到只有128x96的ImageView中显示是不值得的。

为了告知解码器对图像进行抽样,并且把样本加载到内存中,我们需要把BitmapFactory.Options参数中的inSampleSize属性设为true。例如,一张图片的分辨率是2048x1536,如果解码时inSampleSize设为4,这样得到的bitmap大概是512x484。把这张抽样后的图片加载到内存中大约需要0.75M,而把整张图片加到内存确需要12M(假设bitmap模式为ARGB_8888)。这里有一个基于目标宽度和高度来计算inSampleSize的值的方法,这个值是2的倍数。

★ 注意:计算出来的值是2的倍数,这是因为解码器最终使用的数值,都会四舍五入到最靠近的2的倍数。

为了使用这个方法,首先要把inJustDecodeBounds设为true,然后传入这个BitmapFactory.Options参数进行第一次解码,之后设置inSampleSize的值并把inJustDecodeBounds设为false,再进行一次解码。

这个方法可以简单的将一张庞大的图片加载到100x100大小的ImageView中,代码如下:

我们可以根据实际需要替换合适的BitmapFactory类提供的decode方法,然后用相似的过程对其他数据源的图像进行解码。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值