Bitmap 的四种压缩方式详解

47 篇文章 0 订阅
12 篇文章 0 订阅

本文介绍了 Bitmap 压缩的四种方式,相关代码可见:Githhub-GdTestHub


Android 中图片是以 bitmap 形式存在的,那么 bitmap 所占内存,直接影响到了应用所占内存大小,首先要知道 bitmap 所占内存大小计算方式:

像素数 x 像素大小
=
图片长度(单位为像素) x 图片宽度(单位为像素) x 一个像素点占用的字节数

可采用的压缩方法:

  1. 质量压缩:内存不变,压缩转化后的 bytes.length 减少,适用于传输,png 无效
  2. 采样率压缩(Options):改变宽高,减少像素,采用一定的采样算法
  3. 缩放法压缩(Matrix):改变宽高,减少像素,采用一定的缩放算法(数字图像处理相关)
  4. RGB_565:改变字节数

一、质量压缩

样板代码:

val baos = ByteArrayOutputStream()
// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
bmRaw.compress(Bitmap.CompressFormat.JPEG, 50, baos)
val bais = ByteArrayInputStream(baos.toByteArray())
val bmScaled = BitmapFactory.decodeStream(bais, null, null)

说明:

使用 JPEG 格式的质量压缩

bmRaw.compress(Bitmap.CompressFormat.JPEG, 50, baos)
  • 对一张透明图片(png),内存、宽高不变,bytes.length 减少。图片会失去透明度,透明处变黑,
  • 对一张非透明图片(png、jpg),内存、宽高不变,bytes.length 减少。

使用 PNG 格式的质量压缩

bmRaw.compress(Bitmap.CompressFormat.PNG, 50, baos)
  • 对一张透明图片(png),没有影响
  • 对一张非透明图片(png、jpg),没有影响

二、采样率

样板代码:

val options = BitmapFactory.Options()
options.inSampleSize = 2
val bmScaled = BitmapFactory.decodeResource(resources, drawableId, options)
// decode 的方法:
BitmapFactory.decodeFile()
BitmapFactory.decodeRecourse()
BitmapFactory.decodeStream()
BitmapFactory.decodeByteArray()

说明:
在这里插入图片描述
The sample size is the number of pixels in either dimension that correspond to a single pixel in the decoded bitmap.
样本大小是在解码位图中对应于单个像素的任一维度上的像素个数。

也就是说,如果 inSampleSize = 2,采样后的一个像素在 x 轴上相当于之前的 2 个像素,在 y 轴上也相当于之前的 2 个像素。
即采样后的一个像素相当于之前的 2*2=4 个像素。

三、缩放法

样板代码:

val bmRaw = BitmapFactory.decodeResource(resources, drawableId, null)
val matrix = Matrix()
matrix.setScale(0.5f, 0.5f)
val bmScaled = Bitmap.createBitmap(bmRaw, 0, 0, bmRaw.width, bmRaw.height, matrix, true)

说明:
与采样率法类似。

四、RGB_565

样板代码:

val options = BitmapFactory.Options()
options.inPreferredConfig = Bitmap.Config.RGB_565
val bmNew = BitmapFactory.decodeResource(resources, drawableId, options)

说明:
ALPHA_8 代表8位Alpha位图,一个像素1个字节
ARGB_4444 代表16位ARGB位图,一个像素2个字节
ARGB_8888 代表32位ARGB位图,一个像素4个字节
RGB_565 代表16位RGB位图,一个像素2个字节
在这里插入图片描述
如果inPreferredConfig不为null,解码器会尝试使用此参数指定的颜色模式来对图片进行解码,如果inPreferredConfig为null或者在解码时无法满足此参数指定的颜色模式,解码器会自动根据原始图片的特征以及当前设备的屏幕位深,选取合适的颜色模式来解码,例如,如果图片中包含透明度,那么对该图片解码时使用的配置就需要支持透明度,默认会使用ARGB_8888来解码。

所以直接设置 RGB_565:

  • 对于一张透明图片(png),内存、宽高不变,bitmap 也不会失去透明度。
  • 对于一张非透明图片(png、jpg),宽高不变,内存减小。

copy 一遍可以减少内存,但生成的 bitmap 会失去透明度,透明处变黑。

val bmScaled = bmRaw.copy(Bitmap.Config.RGB_565, true)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值