Android:Bitmap 究竟占用多大的内存?
最近有实习生到岗,需要整理课程资料,所以也一并整理Bitmap的知识点。
颜色深度
颜色深度是指单个像素能够显示的颜色数量,通常是用bit作为单位,比如一个24bit的图片,最多能够显示 256x256x256=16777216种颜色。GIF是8bit,只能显示256种颜色。
图片常用格式
GIF(Graphics Interchange Format)
GIF图形交换格式是一种位图图形文件格式,以8位色(即256种颜色)重现真彩色的图像。它实际上是一种压缩文档,采用LZW压缩算法进行编码,有效地减少了图像文件在网络上传输的时间。它是目前广泛应用于网络传输的图像格式之一。
- 优秀的压缩算法使其在一定程度上保证图像质量的同时将体积变得很小。
- 可插入多帧,从而实现动画效果。
- 可设置透明色以产生对象浮现于背景之上的效果。
- 由于采用了8位压缩,最多只能处理256种颜色(2的8次方),故不宜应用于真彩图像。
JPG(Joint Photographic Experts Group)
JPEG是一种针对相片影像而广泛使用的一种失真压缩标准方法。JPEG的压缩方式通常是破坏性资料压缩(lossy compression),意即在压缩过程中图像的品质会遭受到可见的破坏。
PNG(Portable Network Graphics)
便携式网络图片(Portable Network Graphics),简称PNG,是一种无损数据压缩位图图形文件格式。PNG格式是无损数据压缩的,PNG格式有8位、24位、32位三种形式,其中8位PNG支持两种不同 的透明形式(索引透明和alpha透明),24位PNG不支持透明,32位 PNG 在24位基础上增加了8位透明通道。PNG这种类型的图片就是为了取代GIF图片而生的, 除了GIF不支持动画的优势, 能用PNG的地方就用PNG, 原因是压缩比高,色彩好;
WebP
2010年谷歌推迟的图片格式,专门用来在web中使用, 压缩率只有jpg的2/3或者更低; 第一个版本的webp图片格式是有损的, 新版本中webp图片是无损的。在Android开发中已经成为了非常主流的图片格式,大图使用webP,可以有效较低流量和apk体积。
Bitmap像素格式
val bitmap = Bitmap.createBitmap(100,100,Bitmap.Config.ARGB_8888)
Bitmap.Config.ALPHA_8
只有一个alpha通道,占用1Byte。
Bitmap.Config.RGB_565
每个像素占2Byte,其中红色占5bit,绿色占6bit,蓝色占5bit。当图片为JPG格式,无需透明色可选该配置,只需要ARGB_8888一半的内存。
Bitmap.Config.ARGB_4444
每个像素占2Byte,每个通道4bit,从API 13开始不建议使用。
Bitmap.Config.ARGB_8888
每个像素占4Byte,每个通道8bit。这个格式最常用,通常是用于PNG的图片,支持透明度。
Bitmap.Config.RGBA_F16
API 26新增,每个像素占8Byte,支持半精度浮点值,特别适合宽色域和HDR内容。
Bitmap.Config.HARDWARE
API 26新增。
Bitmap 在内存当中占用的大小
从上述的Bitmap像素格式,我们已经可以知道一张图片在内存中的大小,比如100*100,使用ARGB_8888格式的图片内存占用大小为:
100 * 100 * 4 = 40000Byte = 39KB
图片在内存中的大小不等于在存储空间的大小,一张图片的实际存储大小除了和分辨率有关,还和色彩的丰富度有关,色彩越丰富,图片越大。
图片位于不同的res/drawable文件夹对图片大小的影响
Android的drawable提供了多个文件夹,比如drawable-xhdpi、drawable-xxhdpi等,如果我们把一张100x100的图片放在不同的文件夹中,加载出来的Bitmap,宽高并不是都是100x100。
密度 | dpi范围 |
---|---|
ldpi | ~120dpi |
mdpi | ~160dpi |
hdpi | ~240dpi |
xhdpi | ~320dpi |
xxhdpi | ~480dpi |
xxxhdpi | ~640dpi |
我们以一台1080×1920,420dpi的手机为例,一张100x100的图片,通过BitmapFactory.decodeResource()
方法加载,ARGB_8888格式。
scale = 设备dpi / 图片所在文件夹对应的最大dpi
文件夹 | 读取后的宽高 | 占用的内存(Byte) |
---|---|---|
drawable-mdpi | 100 x 420 / 160 = 263 | 263 * 263 * 4 = 276676 |
drawable-hdpi | 100 x 420 / 240 = 175 | 175 * 175 * 4 = 122500 |
drawable-xhdpi | 100 x 420 / 320 = 131 | 131 * 131 * 4 = 68644 |
drawable-xxhdpi | 100 x 420 / 480 = 88 | 88 * 88 * 4 = 30976 |
drawable-xxxhdpi | 100 x 420 / 640 = 66 | 66 * 66 * 4 = 17424 |
从上面的计算可知,一张图片放在合适的文件夹是至关重要的,不同的分辨率对内存有很大影响。
是否需要主动调用Bitmap的recycle方法
Bitmap的recycle方法不是必须主动调用的,实际上垃圾回收是可以回收Bitmap。由于手机的内存的有限的,Bitmap会占用较多的内存,所以及时回收是一个好习惯,但是需要注意的是,不要调用已经执行recycle方法的Bitmap,避免报错。