3. 资源压缩原理:L4压缩与RLE压缩在TouchGFX中的应用场景
资源压缩,说白了就是给图片和字体“瘦身”。
TouchGFX项目里,最占Flash的就是那些PNG、JPG图片和字体文件。我见过不少团队,UI做得很漂亮,结果一编译,Flash超了50%以上。这时候就得靠压缩来救场。
TouchGFX内置了两种压缩算法:L4压缩和RLE压缩。它们各有各的脾气,用对了地方事半功倍,用错了反而会让性能崩掉。
3.1 两种压缩算法的核心差异
先看一张对比表,心里有个底:
| 特性 | L4压缩 | RLE压缩 |
|---|---|---|
| 全称 | LZ4(Lempel-Ziv 4) | Run-Length Encoding |
| 压缩原理 | 基于字典匹配,查找重复数据块 | 统计连续相同像素值,用“值+计数”替代 |
| 压缩比 | 较高(通常2:1 ~ 5:1) | 较低(通常1.5:1 ~ 3:1) |
| 解压速度 | 极快(约400-500 MB/s) | 非常快(约800-1000 MB/s) |
| 适用场景 | 复杂图片、渐变、照片类资源 | 大面积纯色、图标、简单图形 |
| 内存开销 | 需要额外字典缓冲区 | 几乎无额外内存 |
我个人习惯这样选:图片复杂、颜色丰富 → L4;大面积纯色、简单图标 → RLE。这个原则帮我避过不少坑。
3.2 L4压缩:字典匹配的威力
L4压缩的核心思路是:找重复。它会把数据流切分成一个个小段,然后建立一个滑动窗口字典。遇到之前出现过的数据块,就直接用“位置+长度”来替换。
举个例子,一张渐变背景图,里面有很多相似的像素序列。L4能识别出这些重复模式,用短短几个字节代替一大段数据。
关键点:L4的解压速度非常快,因为它不需要复杂的数学运算,只需要查字典和拷贝内存。在TouchGFX里,解压一张800x480的图片,L4通常能在1-2毫秒内完成。
我在项目中遇到过一个问题:某张产品渲染图用了L4压缩,压缩比达到了4.2:1,但解压时偶尔会出现画面撕裂。后来发现是DMA传输和CPU解压的时序没配合好。解决办法很简单——把解压操作放到刷新周期的空闲时段执行。
小技巧:L4的压缩等级可以调节。TouchGFX默认使用“快速模式”,如果你对压缩比有更高要求,可以尝试“高压缩模式”,但编译时间会变长。我个人建议:开发阶段用快速模式,发布前再用高压缩模式跑一次。
3.3 RLE压缩:简单粗暴的纯色杀手
RLE压缩的原理更直白:数一数连续相同的像素有多少个。
比如一张图标,背景全是白色(0xFFFF),图标本身是黑色(0x0000)。RLE会把数据变成这样:
原始数据(16位色):FFFF FFFF FFFF FFFF 0000 0000 FFFF FFFF
RLE编码后:4xFFFF, 2x0000, 2xFFFF
你看,原本16个字节的数据,压缩后只需要12个字节。如果纯色区域更大,压缩比会更可观。
但RLE有个致命弱点:遇到颜色频繁变化的区域,压缩比会暴跌,甚至出现“负压缩”——压缩后的数据比原来还大。
避坑指南:我曾经把一张照片风格的按钮背景图用了RLE压缩,结果编译出来的资源比没压缩还大了15%。后来检查才发现,照片里几乎没有连续相同的像素,RLE反而增加了存储开销。从那以后,我定了个规矩:RLE只用于图标、边框、纯色背景这类资源。
3.4 压缩比与解压速度的权衡
这是本章最核心的问题。你想想看,压缩比高了,Flash省了,但解压时间长了,可能拖慢帧率。反过来,解压速度快了,压缩比可能不够,Flash又吃紧。
我整理了一个实际项目的测试数据,供你参考:
| 资源类型 | 原始大小 | L4压缩后 | RLE压缩后 | L4解压耗时 | RLE解压耗时 |
|---|---|---|---|---|---|
| 渐变背景(800x480) | 768 KB | 192 KB(4:1) | 512 KB(1.5:1) | 1.8 ms | 0.9 ms |
| 纯色图标(32x32) | 2 KB | 1.2 KB(1.7:1) | 0.4 KB(5:1) | 0.05 ms | 0.02 ms |
| 照片(400x300) | 234 KB | 58 KB(4:1) | 210 KB(1.1:1) | 0.6 ms | 0.5 ms |
看到没?没有绝对的“最好”,只有“最合适”。渐变背景用L4,压缩比高,解压时间也能接受。纯色图标用RLE,压缩比直接飙到5:1,解压几乎不花时间。照片嘛,老老实实用L4,RLE基本帮不上忙。
3.5 知识体系总览
下面这张图,把两种压缩算法的选择逻辑串起来了:
3.6 实际项目中的选择策略
说了这么多理论,来点实际的。我在一个智能家居面板项目里,总结了一套选择策略:
- 先分类:把所有图片资源分成“复杂”和“简单”两类。复杂包括照片、渐变、纹理;简单包括图标、按钮、纯色背景。
- 复杂资源用L4:压缩比高,解压速度也够用。注意避开刷新高峰期。
- 简单资源用RLE:特别是那些大面积纯色的图标,RLE能压到原始大小的20%以下。
- 混合使用:同一个屏幕里,背景用L4,图标用RLE,TouchGFX完全支持。
- 测试验证:编译后检查Flash占用,运行时用性能分析工具看解压耗时。如果发现某个资源解压时间超过2ms,考虑换算法或降低分辨率。
个人经验:我习惯在TouchGFX Designer里给每个资源手动指定压缩方式,而不是用全局设置。虽然麻烦一点,但能精确控制每个资源的压缩效果。全局设置容易“一刀切”,导致某些资源表现不佳。
嗯,压缩原理这部分就聊到这儿。记住一句话:没有最好的压缩算法,只有最合适的场景。L4和RLE就像工具箱里的两把扳手,知道什么时候用哪一把,才是真本事。