近乎完全搞懂Bitmap的内存计算(一)

前言

不少同窗面试的时候常常会遇到这样的问题,怎样计算一张图片所占的内存,也许你会说先计算像素点也就是图片的宽*高,而后再乘以每一个像素所占的内存,就能够计算获得,这种方法有必定的正确性,可是要在特定的状况下,接下来咱们一一来分析。java

正文

首先咱们来了解一下Bitmap.Config,andrdoid官方提供的文档咱们知道经常使用有以下几种:面试

名称 位数 所占内存
ALPHA_8 8 1
RGB_565 16 2
ARGB_4444 16 2
ARGB_8888 32 4

咱们知道Bitmap能够经过decodeStream()以及decodeResource()两种方法获取,先来看第一种:代码以下:bash

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占用的内存就是这样计算呢?非也!请看以下代码:spa

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占用的内存计算公式以下code

占用内存 = 图片宽度/inSampleSize*图片高度/inSampleSize*每一个像素所占的内存
复制代码

接下来再来看下decodeResource()方式,以下:cdn

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,貌似也符合以下的公式:blog

占用内存 = 图片宽度/inSampleSize*图片高度/inSampleSize*每一个像素所占的内存
复制代码

然而事情没有那么简单,接下来咱们把图片换个位置,分别放在mdpi、hdpi、以及xxhdpi,结果分别是40000、1795六、4356,有发现什么规律么?看下面这个表格图片

如今能发现规律么?先说结论,经过 decodeResource() 方式生成的Bitmap,占用的内存除了和图片的宽高、options.inPreferredConfig、options.inSampleSize相关以外还和当前设备的 dpi( inTargetDensity ) 与图片所在文件夹对应的 dpi( inDensity ) 有关,经过上面的结果,咱们能够知道具体的换算关系以下:

占用内存 = 图片宽度/inSampleSize*inTargetDensity/inDensity*图片高度/inSampleSize**inTargetDensity/inDensity*每一个像素所占的内存
复制代码

具体为啥是这样,咱们下期结合源码进行分析!ip

相关文章
相关标签/搜索