Loading Large Bitmaps Efficiently[高效加载大图]
0x00、 高效加载大图片
原文:https://developer.android.com/topic/performance/graphics/load-bitmap
☆NOTE: 一些使用最佳实践方式加载图片的库。 你能在你的 app 中使用这些库用最优的方式加载图片。 我们推荐快速流畅加载图片的 Glide 库。 其他流行的图像加载库还有来自 Facebook 的 Square 和 Fresco 的 Picasso。 这些库简化了 Android 平台上有关图像的复杂操作。
图像有多种形状和尺寸。 在多数情况下他们的尺寸大于展示它们的 UI 。 例如系统应用 Gallery(画廊) 展示照相机拍摄的照片的时候,照片解析度是普遍高于屏幕密度的。
在内存受限制的情况下,比较理想的做法是加载低解析度的图片到内存。 低解析度的版本的尺寸应该和展示它的 UI 的尺寸相匹配。 具有更高分辨率的图像不会提供任何明显的好处,但仍会占用宝贵的内存并因额外的动态扩展而产生额外的性能开销。
本篇文字介绍了:在不超过 app 内存限制的情况下通过在内存中加载大图片的缩略图,的方式展示图片。
0x01、 读取 Bitmap 的尺寸和类型。
BitmapFactory 为创建 Bitmap 对象提供了一系列解码方法(decodeByteArray(),decodeFile(),decodeResource()等)。 选择适当的方法解码你的图像资源。 这些方法尝试在构造位图的时候会尝试为其分配内存空间,这时候容易发阿生 OutOfMemory 异常。 每一种解码方式都能通过增加标记的方式指定解码选项变量 BitmapFactory.Options 类对象。 设置 inJestDecodeBounds 属性为 true 可以避免解码图片过程中的内存分配,这样解码方法将会 return null ,但是 BitmapFactory.Options 对象中的 outWidth, outHeight, 和 outMimeType 却被设置了值。
要避免 java.java.OutOfMemory
异常,可在真正解码图片之前检查 bitmap 的尺寸,除非你绝对信任提供的携带可预见尺寸的图像数据资源,否则就要修正资源使打到内存可接受的程度。
0x02、 加载缩放过的图片到内存中
现在待加载图片的尺寸是已知的,可以通过它决定是应该将其全部加载到内存还是加载其缩略图。 这里是一些做这个决定所需要考虑的因素:
预计加载整个图像需要占用的内存空间。
其他通过你的 App 获取图片的时候,留意他们想要的图片所占的内存大小。
目标 ImageView 或者其他 UI 展示图片的控件的尺寸。
当前设备的屏幕大小和像素密度。
例如,为大小为 128×96pix 的 ImageView 加载 1024×768pix 的图片是没有价值的。
要将一个图片解码为更小的版本,需要将你的 BitmapFactory.Option 的 inSampleSize 设置为 true 。 例如,一个解析度为 2048×1536 的图片要将其解析为原图的 1/4 约为 512x384(假设位图的配置为 ARGB_8888) 。这时候内存的占用量将会是 0.75MB 而不是 2MB 。 下面是一个基于宽度和高度计算图片缩放比率的方法:
☆NOTE: 使用 2 作为因子是因为解码器使用最终值通过舍入得到最接近的 2 的幂。
使用这个方法,首次解码的时候 inJustDecodeBounds 设置为 true ,获取 options 值,然后使用新的 inSampleSize 对图片进行解码的时候 inJustDecodeBound 设置为 false :
这个方法使得加载一个大图的缩略图到一个 100x100pix 的 ImageView 变的简单。
你能按照上面的例子从不同的数据源解码图片。
Last updated