前言:
在前面的demo编写过程中,我一直想不通的就是,为啥我的app就一点东西,却占很大的内存,也没写啥东西,后来才发现,原来是背景图片占内存,今天就来学习下Android中图片占内存的计算方法。
学习:
一、颜色模式
Android中有四种颜色模式,分别为:
ALPHA_8:每个像素占用1byte内存
ARGB_4444:每个像素占用2byte内存
ARGB_8888:每个像素占用4byte内存
RGB_565:每个像素占用2byte内存
默认的为ARGB_8888,因为这种颜色模式色彩最细腻,显示质量高。但是同样的,占用的内存大。
举个栗子说下:比如一张32位的PNg图片(也就是ARGB_8888),像素是1024*1024,那么,占用的内存为:1024*1024*(32/8)(8bit = 1byte)= 4 mb
所以,为了避免oom,我们最好选择ARGB_4444模式的图片,节省了一半的内存
二、图片相关的概念
像素:是组成图片的最基本单元元素
分辨率:是指在长和宽上各拥有的像素个数
比如:有张分辨率是1080*1920的图片,那就意味着它的宽度方向上有1080个像素点,高度方向上有1920个点,所以这张照片总共拥有2073600个像素点
三、图片占用内存大小的计算
3.1 图片的载体
图片加载到内存后是以bitmap的形式存在的,所以bitmap占用内存空间大小就是图片在内存中占用空间的大小
3.2 bitmap占用内存空间的计算
Bitmap的内存大小是以图片像素点总数乘以每个像素点所占的内存的大小的结果。所以图片占用内存的大小只跟图片分辨率和每个像素点占用的内存大小有关。如上面讲的
四、demo实验
我们随意写个登录的界面,未加载背景图片时 14.94mb
加载图片后:16.38mb
我们可以看出多用了1.44mb,我们来看下图片的分辨率
我们可以看到,它是8位1byte的分辨率为128*245的图片,如果,我们根据上面的公式计算:128*245*1/1024 = 30.625kb 远没有这么多,那么问题出现在哪?
我们忽略了一个问题,这是它本身的分辨率,我们知道png的图片是可以变化的,我们来看下手机的分辨率
可以得到手机的分辨率为1920*1080,那么,我们用手机的分辨率来算一算
1080*1920*1/1024 = 2015kb / 1024 = 1.97mb
但是,结果又太大了
仔细想想,我们这个图片是存在drawable中的,难道,这个里面也有规则,花点时间查了资料了解到:
图片的大小放在各个drawable文件夹下载下列对应的像素密度:
Mdpi > 160 dpi
Hdpi > 240dpi
Xhdpi > 320dpi
Xxhdpi > 480dpi
Xxxhdpi > 640dpi
那么问题来了,像素密度是啥?
像素密度,即每英寸屏幕所拥有的像素数,像素密度越大,显示画面细节就越丰富。像素密度=√{(长度像素数^2+宽度像素数^2)}/ 屏幕尺寸
好了,了解了像素密度后,我们来学习其中的奥秘
举个例子:
加入分辨率为1080*1920的图片放在xxhdpi对应的文件夹下,则480dpi的手机上的bitmap的大小是1080*1920,否则,其他大小dpi的手机的算法如下:
420dpi:
宽:1080*(420/480) = 945
长:1920*(420/480) = 1680
这个时候,图片的大小为945*1680
通过代码得到我的手机dpi为403.5
这个时候,我们再去计算:
1080*1920*403.5*403.5/480/480/1024/1024 = 1.4mb
刚好是这个值
所以,通过这个实验可以得到
图片的大小(分辨率)是在手机上显示时的大小(分辨率),而且是通过dpi来计算结果的
附加:得到dpi的demo
关于怎么优化,我们后面再讲。
在写这个的时候,在网上找了不少文章,如果原作者觉得侵权,请联系我删除该文章。