一、质量压缩原理
核心机制:通过降低图片的色彩精度和细节保留度来减小文件体积,本质是有损压缩。
实现方法:调用 Bitmap.compress(CompressFormat format, int quality, OutputStream stream)
-
format:压缩格式(JPEG/PNG/WEBP)
-
quality:压缩质量(0-100,0最差/体积最小,100最佳/体积最大)
-
stream:输出流(保存压缩结果)
技术本质:
-
JPEG:采用离散余弦变换(DCT),通过量化表减少高频分量(图像细节),再对数据块进行哈夫曼编码
-
PNG:无损压缩,
quality
参数无效(但可减少颜色位数) -
WEBP:结合预测编码和变换编码,比JPEG节省约30%体积
关键特性:
// 示例:质量压缩代码
ByteArrayOutputStream baos = new ByteArrayOutputStream();
sourceBitmap.compress(Bitmap.CompressFormat.JPEG, 60, baos); // 压缩到60%质量
byte[] compressedData = baos.toByteArray();
-
✅ 文件体积减小:适合网络传输或本地存储
-
❌ 内存占用不变:解码后内存大小仍由原始宽高决定
-
❌ 像素数据未减少:图片尺寸(width×height)不变
-
❌ 图像质量变差:压缩之后会丢失高频信息,而该信息不可恢复
二、Bitmap 完整压缩机制
除质量压缩外,Android 还有两类核心压缩方式:
1. 尺寸压缩(采样率压缩)
原理:减少像素数量(物理尺寸)
实现:通过 BitmapFactory.Options.inSampleSize
控制采样率
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2; // 宽高缩小为1/2,像素数降为1/4
Bitmap sampledBitmap = BitmapFactory.decodeFile(path, options);
效果:
-
✅ 内存占用显著降低(与像素数正相关)
-
✅ 文件体积减小(解码后数据变少)
-
❌ 可能造成图像模糊(取决于采样率)
2. 色彩空间压缩
原理:改变像素存储格式
options.inPreferredConfig = Bitmap.Config.RGB_565; // 每个像素占2字节
格式 | 字节/像素 | 特性 |
---|---|---|
ARGB_8888 (默认) | 4字节 | 支持透明度和1600万色 |
RGB_565 | 2字节 | 无透明度,6.5万色 |
ARGB_4444 (废弃) | 2字节 | 质量差,API 30+ 已弃用 |
效果:
-
✅ 内存直接减少50%(RGB_565 vs ARGB_8888)
-
❌ 色彩细节损失(尤其渐变场景)
总结
问题: Bitmap 的质量压缩原理
回答:
Android 的质量压缩是通过Bitmap.compress()
方法实现的有损压缩。它调整图片的编码质量参数(0-100),主要作用于 JPEG/WEBP 格式。其核心原理是:
对色彩数据进行离散余弦变换(DCT),分离高频/低频分量
通过量化表降低高频细节(人眼不敏感部分)的精度
使用哈夫曼编码压缩数据块
这种压缩会减小文件体积,但不改变图片尺寸,解码后内存占用不变,适合网络传输场景。
问题:Bitmap 有哪些压缩方式?
回答:
完整的 Bitmap 压缩需结合三种手段:
第一是尺寸压缩:通过inSampleSize
控制解码采样率,例如设为2时宽高减半,内存降为1/4,这是解决OOM的关键手段。
第二是色彩压缩:使用RGB_565
替代默认ARGB_8888
,内存直接减半,但会损失透明度。
第三是质量压缩:作为辅助手段,用于进一步减小存储体积。实际开发中通常组合使用:先尺寸压缩控制内存,再质量压缩优化存储。
问题:为什么质量压缩后内存没变少?
回答:
因为质量压缩仅改变编码后字节流的密度(文件体积),而Bitmap内存占用由像素矩阵决定。例如一张 1920x1080 的图片:
解码后内存恒为
1920×1080×4 ≈ 7.9MB
(ARGB_8888)质量压缩到50%可能使文件从2MB变为200KB,但加载到内存仍需7.9MB
要减少内存必须通过尺寸压缩或更改色彩格式。
问题:WEBP 和 JPEG 压缩有何区别?
回答:
JPEG:
基于DCT变换,擅长压缩照片类图像
不支持透明度,高压缩率时易产生块状伪影
WEBP:使用预测编码(VP8技术),同等质量体积比JPEG小30%
支持有损/无损压缩和透明度
Android 4.0+ 原生支持,是当前推荐的图片格式
关键总结表
压缩类型 | API/参数 | 内存影响 | 文件体积 | 使用场景 |
---|---|---|---|---|
质量压缩 | compress(quality=0-100) | 无变化 | 显著减小 | 图片上传、本地存储 |
尺寸压缩 | inSampleSize | 平方级减少 | 减小 | 加载大图防OOM |
色彩空间压缩 | inPreferredConfig | 减少50% | 无直接影响 | 不透明图片内存优化 |