1、概述
现在的ImageView 图片加载 url 都是用框架加载了,用的比较多的 有
ImagLoader 比较早的经典
fresco facebook 出的
picasso square这个开源组织出的
Glide 谷歌推荐
但是这不是重点,此篇想表达的就是框架用多了 反而一些基础性的东西不知道怎么算了,在优化上反而不知道借助框架结合基础使用。
2、概念
Imageview在内存中占用的空间 涉及到几个概念
Imageview 基础控件 图片展示的承载控件
bitmap 简单的理解为 图片在内存的存储形势,可以理解为图片流
BitmapFactory.Options bitmap的一些属性 其中典型的就是
inSampleSize 采样 详细描述见源码里的注释:就是该值>=1 开始生效,小于1按1算,都是2的倍数
如果inSampleSize = 4 就是bitmap 长宽各取src的 1/4 内存等于src的 1/16.
For example, inSampleSize == 4 returns * an image that is 1/4 the width/height of the original, and 1/16 the * number of pixels. Any value <= 1 is treated the same as 1. Note: the * decoder uses a final value based on powers of 2, any other value will * be rounded down to the nearest power of 2.
inPreferredConfig bitmap的对齐格式常用的是 565 8888 在源码里可以看是enum 类型。在这里提下源码中对565 8888的注释,主要是为了后续的计算时 清楚计算的大小转放
ALPHA_8
RGB_565Each pixel is stored on 2 bytes.
参见源码解释,每个像素点是2 byte 16bit
ARGB_4444
ARGB_8888
Each pixel is stored on 4 bytes.
参见源码解释,每个像素点是4byte 32bit
inJustDecodeBounds 该值为true的话 BitmapFactory 只是解析图片 并不会真正的加载
BitmapFactory相关解析图片成bitmap的函数罗列几个:想表达的就是Options 的重要,没有Options 参数的是缺省形势
public static Bitmap decodeFile(String pathName, Options opts) {
public static Bitmap decodeResource(Resources res, int id, Options opts) {
问题:比如xml中放置一个ImageView 大小是(400*800像素) 去加载一张1080p的图 (1080*1920像素)那么该Imageview占用多少内存。
该问题是我们关心的:但是实际上,真正占用内存的是bitmap,那么其实可以分成两个问题
a、1080p的图直接加载是多大的bitmap
b、最后用在400*800ImageView上是多大的bitmap
对于a:
1080p的图不管是jpg 还是png(和图片压缩方式无关大小有关) 如果按默认加载方式
inPreferredConfig = ARGB_8888(4 byte) inSampleSize =1
src_bitmap_length = 1920*1080* 4 / (1^2)= 8294400 byte = 8294400 /1024/1024 m = 7.91m
注:1KB = 1024Byte 1MB = 1024KB
对于b:
就发现该问题不是问题了,a算出来的大小就是b的
4、优化方式
整个ImageView 加载图片的内存占用计算就是上文所示。所以如果要优化 内存占用空间
就是在inPreferredConfig (这个大图没有透明的话用565是可以的) 和 inSampleSize (这个可以计算) 上做处理了