前言
很多同学面试的时候经常会遇到这样的问题,怎样计算一张图片所占的内存,也许你会说先计算像素点也就是图片的宽*高,然后再乘以每个像素所占的内存,就可以计算得到,这种方法有一定的正确性,但是要在特定的情况下,接下来我们一一来分析。
正文
首先我们来了解一下Bitmap.Config,andrdoid官方提供的文档我们知道常用有如下几种:
名称 | 位数 | 所占内存 |
---|---|---|
ALPHA_8 | 8 | 1 |
RGB_565 | 16 | 2 |
ARGB_4444 | 16 | 2 |
ARGB_8888 | 32 | 4 |
我们知道Bitmap可以通过decodeStream()以及decodeResource()两种方法获取,先来看第一种:代码如下:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeStream(getAssets().open("demo.jpg"), null, options);
textView.setText(String.valueOf(bitmap.getByteCount()));
为了便于计算我这里demo.jpg的宽和高都是100,结果是40000,符合如下计算公式:
占用内存 = 图片宽度*图片高度*每个像素所占的内存
再把ARGB_8888改成RGB_565,结果是20000,改成ARGB_4444也是20000,那么是否意味着通过decodeStream()方式获取的Bitmap占用的内存就是这样计算呢?非也!请看如下代码:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
options.inSampleSize = 2;
Bitmap bitmap = BitmapFactory.decodeStream(getAssets().open("girl.jpg"), null, options);
textView.setText(String.valueOf(bitmap.getByteCount()));
结果是10000,我们知道inSampleSize表示的是采样率,为2的整数次幂,根据官方文档解释,设置了inSampleSize,图片的宽高对应的缩小inSampleSize倍数,上面的结果也验证了,所以decodeStream()方式获取的Bitmap占用的内存计算公式如下
占用内存 = 图片宽度/inSampleSize*图片高度/inSampleSize*每个像素所占的内存
接下来再来看下decodeResource()方式,如下:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
options.inSampleSize = 2;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.girl, options);
textView.setText(String.valueOf(bitmap.getByteCount()));
首先我的的测试手机是720p的,对应的资源文件夹是xhdpi,我把图片放到对应的文件夹下面,运行如上代码,得出的结果是10000,貌似也符合如下的公式:
占用内存 = 图片宽度/inSampleSize*图片高度/inSampleSize*每个像素所占的内存
然而事情没有那么简单,接下来我们把图片换个位置,分别放在mdpi、hdpi、以及xxhdpi,结果分别是40000、17956、4356,有发现什么规律么?看下面这个表格
现在能发现规律么?先说结论,通过 decodeResource() 方式生成的Bitmap,占用的内存除了和图片的宽高、options.inPreferredConfig、options.inSampleSize相关职位还和当前设备的 dpi( inTargetDensity ) 与图片所在未见夹对应的 dpi( inDensity ) 有关,通过上面的结果,我们可以知道具体的换算关系如下:
占用内存 = 图片宽度/inSampleSize*inTargetDensity/inDensity*图片高度/inSampleSize**inTargetDensity/inDensity*每个像素
最后
如果你看到了这里,觉得文章写得不错就给个赞呗!欢迎大家评论讨论!如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足,定期免费分享技术干货。感兴趣的小伙伴可以点一下关注哦。谢谢!