图片内存小结

同一张图片,放在不同目录下,会生成不同大小的Bitmap
Bitmap的长度和宽度越大,占用的内存就越大
图片在硬盘上占用的大小,与在内存中占用的大小完全不一样

我们以放在drawable文件夹下面的图片为例,加载到内存之后,2160*3840大小的Bitmap占用的内存为

2160 * 3840 * 4 = 3317,7600 byte = 3,2400kb = 31.640625 M

所以drawable文件夹下的App内存占用 = 原始内存8.31M+图片内存31.64M= 39.95M ,与实际内存占用39.88M存在0.1755%的误差,在误差范围之内。

长*宽是图片的像素总数,乘以4则是因为一个像素占用A、R、G、B四个通道,每个通道占用8位,所以描述一个像素需要32位即4个字节。

一个颜色通道需要8位描述,2^8=256,所以每个颜色通道就有256种状态。如果把彩色图转化成灰阶图的话,也有256种状态分割从白色到黑色之间的过渡颜色。

当然,也并不是所有格式的图片每个像素占用4字节,这和图片在加载时设置的Bitmap.Config有关,默认的是Bitmap.Config.ARGB_8888,其他类型如下:

Bitmap.Config.ALPHA_8 此时图片只有alpha值,没有RGB值, 一1个像素占用一个字节
Bitmap.Config.ARGB_4444 一个像素占用2个字节,alpha(A)值,Red(R)值,Green(G)值,Blue(B)值各占4个bites共16bites,即2个字节
Bitmap.Config.ARGB_8888 一个像素占用4个字节,alpha(A)值,Red(R)值,Green(G)值,Blue(B)值各占8个bites,共32bites,即4个字节。这是一种高质量的图片格式,在电脑上普通采用。它也是Android手机上一个Bitmap的默认格式。
Bitmap.Config.RGB_565 一个像素占用2个字节,没有alpha(A)值,即不支持透明和半透明,Red(R)值占5个bites ,Green(G)值占6个bites ,Blue(B)值占5个bites,共16bites,即2个字节。对于没有透明和半透明颜色的图片来说,该格式的图片能够达到比较的呈现效果,相对于ARGB_8888来说也能减少一半的内存开销。因此它是一个不错的选择。

内存和占硬盘大小区别

为什么在硬盘上存储只需要77.11k,放到内存里面就需要30多M呢?因为这根本不是一回事。
存放在硬盘上的图片文件,会根据各自的压缩规则进行压缩,比如Jpeg这种有损压缩的图片格式,最常使用可变字长编码的哈弗曼编码,会使用哈弗曼树,也就是最优二叉树,根据某些数据出现的频率对数据段编码,从而减少占用的硬盘大小。
比如说“10111”这个序列在图片的二进制数据中出现的概率最大,那我们可以用“01”来代替这一段数据,原来5位的数据,用2位就可以表示了,这就是压缩率60%。当然这只是打个比方,在实际操作中需要考虑“异前缀原则”等编码的基本原则。
而如果把图像读取到内存中就不一样了,因为我们需要每一个像素都能在屏幕上显示,所以会把每个像素点都加载至内存中,不会对相同像素进行压缩或者是替换,所以你也应该能明白前面提到的Bitmap占用内存大小的计算公式的由来了。

不同目录下内存使用情况

那么为什么“同一张图片,放在不同目录下,会生成不同大小的Bitmap”呢?
我的测试设备为锤子T1,1080*1960,xxhdpi,所以说,如果把这张放置在xxhdpi的话,应该不会对图像进行放缩,也就是原始大小,所以我们在前面得到drawable-xxhdpi文件夹下,图片大小为720 * 1280是完全可以理解的,就是图片本身的大小。
当图片放置在drawable-hdpi中时,图片大小为1440 * 2560,长宽变为原来的两倍,这是因为不同分辨率之间的倍数关系导致的

ldpi:240x320 3/4倍
mdpi:320x480 1
hdpi:480x800 1.5倍
xhdpi:960*720 3倍
xxhdpi:1280×720 4倍

我们可以很明显的看到xxhdpi是hdpi的2倍,所以如果单独放置在某个drawable文件夹,手机会自动根据当前的屏幕密度对图片进行放缩。

比如上面,当把图片放置在xxxhdpi里面的时候,在xxhdpi的设备上,图片长 = 720 * (3/4) = 540,图片宽 = 1280 * (3/4) = 960,这与上面的测试结果是完全一致的。

drawable-mdpi是系统默认的像素密度,drawable和drawable-mdpi是一样的大小,其他像素密度都以它为基数,当只在drawable中存在图片时,如果使用该图片,那么将按照drawable-mdpi的放缩比例进行放缩。

如果把一个本来应该放在drawable-xxhdpi里面的图片放在了drawable文件夹,在xxhdpi设备上,图片会被放大3倍,图片内存占用就会变为原来的9倍。

张鹏宇

继续阅读此作者的更多文章