| — | — | — | — |
| 10 | 图片位于res/drawable,设备dpi=240,设备1dp=1.5px | 4393440B(4.19MB) | 序号1 |
| 11 | 图片位于res/drawable-hdpi,设备dpi=240,设备1dp=1.5px | 1952640B(1.86MB) | 序号3 |
| 12 | 图片位于res/drawable-xhdpi,设备dpi=240,设备1dp=1.5px | 1098360B(1.05MB) | 序号4 |
| 13 | 图片位于磁盘中,设备dpi=240,设备1dp=1.5px | 1952640B(1.86MB) | 序号9 |
这里列出的几种场景,每个场景比较的实验对象序号也写在每行最后了,大伙可以自己比对确认一下,是不是发现,数据都是一样的,所以这里可以先得到一点结论:
图片的不同格式:png 或者 jpg 对于图片所占用的内存大小其实并没有影响
好了,我们开始来分析这些实验数据:
首先,如果按照图片大小的计算公式:分辨率 * 像素点大小
那么,这张图片的大小按照这个公式应该是:1080 * 452 * 4B = 1952640B ≈ 1.86MB
ps: 这里像素点大小以 4B 来计算是因为,当没有特别指定时,系统默认为 ARGB_8888 作为像素点的数据格式,其他的格式如下:
-
ALPHA_8 – (1B)
-
RGB_565 – (2B)
-
ARGB_4444 – (2B)
-
ARGB_8888 – (4B)
-
RGBA_F16 – (8B)
上述实验中,按理就应该都是这个大小,那,为什么还会出现一些其他大小的数据呢?所以,具体我们就一条条来分析下:
分析点1
先看序号 1,2 的实验,这两者的区别仅在于图片显示的空间的大小上面。做这个测试是因为,有些人会认为,图片占据内存空间大小与图片在界面上显示的大小会有关系,显示控件越大占用内存越多。显然,这种理解是错误的。
想想,图片肯定是先加载进内存后,才绘制到控件上,那么当图片要申请内存空间时,它此时还不知道要显示的控件大小的,怎么可能控件的大小会影响到图片占用的内存空间呢,除非提前告知,手动参与图片加载过程。
分析点2
再来看看序号 2,3,4 的实验,这三个的区别,仅仅在于图片在 res 内的不同资源目录中。当图片放在 res 内的不同目录中时,为什么最终图片加载进内存所占据的大小会不一样呢?
如果你们去看下 Bitmap.decodeResource()
源码,你们会发现,系统在加载 res 目录下的资源图片时,会根据图片存放的不同目录做一次分辨率的转换,而转换的规则是:
新图的高度 = 原图高度 * (设备的 dpi / 目录对应的 dpi )
新图的宽度 = 原图宽度 * (设备的 dpi / 目录对应的 dpi )
目录名称与 dpi 的对应关系如下,drawable 没带后缀对应 160 dpi:
所以,我们来看下序号 2 的实验,按照上述理论的话,我们来计算看看这张图片的内存大小:
转换后的分辨率:1080 * (240/160) * 452 * (240/160) = 1620 * 678
显然,此时的分辨率已不是原图的分辨率了,经过一层转换,最后计算图片大小:
1620 * 678 * 4B = 4393440B ≈ 4.19MB
这下知道序号 2 的实验结果怎么来的了吧,同样的道理,序号 3 资源目的是 hdpi 对应的是 240,而设备的 dpi 刚好也是 240,所以转换后的分辨率还是原图本身,结果也才会是 1.86MB。
小结一下:
位于 res 内的不同资源目录中的图片,当加载进内存时,会先经过一次分辨率的转换,然后再计算大小,转换的影响因