3、图像资源压缩:L8、A4、RLE格式选择与PNG/JPEG预处理

图像资源,往往是TouchGFX项目里内存占用的头号大户。我见过不少项目,UI逻辑写得挺漂亮,结果一编译,Flash超了,RAM也爆了。查来查去,罪魁祸首就是几张没处理过的PNG。

这一章,咱们就专门聊聊怎么给图像资源“瘦身”。说白了,就是选对格式、做对预处理。你想想看,一张图如果能从RGBA8888压缩到L8,内存直接省掉75%。这买卖,划算。

3.1 理解TouchGFX的像素格式家族

TouchGFX支持好几种像素格式。但真正能帮你省内存的,其实就那几种。我习惯把它们分成两类:“真彩色系”和“索引/压缩系”。

格式 位深 适用场景 内存占用(相对RGBA8888)
RGBA8888 32位 照片、高精度渐变、半透明特效 100%
RGB565 16位 无透明通道的普通界面元素 50%
L8 8位 图标、单色背景、颜色数≤256的图像 25%
A4 4位 仅需透明通道的遮罩、阴影 12.5%
RLE 可变 大面积纯色块、简单几何图形 取决于内容,通常极低

核心原则:能用L8,就别用RGB565。能用A4,就别用L8。能用RLE,就别用原始格式。每降低一位,省的可都是真金白银的Flash和RAM。

3.2 L8格式:索引色的威力

L8,全称是8位索引色。它不直接存每个像素的颜色值,而是存一个“调色板索引”。图像里最多256种颜色,每种颜色在调色板里占4字节(RGBA8888)。

举个例子。一张32x32的图标,如果用RGBA8888,大小是32x32x4=4096字节。转成L8后,图像数据只有32x32x1=1024字节,再加上调色板256x4=1024字节。总共2048字节。省了一半。

什么时候用L8?

  • 图标、按钮、小控件
  • 颜色数少于256的插图
  • 不需要平滑渐变的背景

我的经验:在项目中,我习惯把所有图标都先转成L8试试。如果视觉上没明显差异,就直接用。有一次,一个包含200多个图标的项目,光这一步就省了将近300KB的Flash。嗯,这300KB后来全用来放中文字库了。

3.3 A4格式:透明通道的极致压缩

A4格式很有意思。它只存透明通道,不存颜色信息。每个像素用4位表示透明度,也就是16级透明度。

你可能会问:“只有透明,没有颜色,那显示出来是什么?”答案是:它通常作为遮罩或阴影使用。比如一个按钮的阴影,只需要知道哪里透明、哪里半透明、哪里不透明。颜色?让上层图层的颜色透过来就行。

什么时候用A4?

  • 投影、发光、模糊边缘
  • 不规则形状的遮罩
  • 任何只需要透明信息的图像

避坑指南:我曾经在一个项目里,把一张带渐变色的背景图强行转成了A4。结果显示出来一片灰蒙蒙,因为A4不存颜色信息。记住,A4只存透明,不存颜色。颜色信息得靠其他图层提供。

3.4 RLE格式:游程编码的妙用

RLE,Run-Length Encoding,游程编码。它的原理很简单:把连续的相同颜色像素压缩成一个“长度+颜色值”对。

比如一行像素:红红红红红蓝蓝蓝绿绿。RLE编码后变成:5红 3蓝 2绿。如果图像里大块大块都是纯色,压缩率会非常惊人。

什么时候用RLE?

  • 大面积纯色背景
  • 简单的几何图形(矩形、圆角矩形)
  • 文字轮廓(如果文字颜色单一)

注意:RLE的解码需要额外CPU开销。如果图像内容很“碎”(比如照片),RLE反而可能比原始格式还大。所以,RLE只适合内容简单的图像。

3.5 PNG/JPEG预处理:从源头控制

很多人直接把设计师给的PNG扔进TouchGFX Designer。这是个大坑。设计师给的PNG,往往是32位带Alpha通道的,尺寸也可能是2倍甚至3倍的分辨率。

预处理步骤:

  1. 降位深:如果不需要透明,果断转成RGB565或L8。如果需要透明,评估能否用A4。
  2. 缩分辨率:确认UI设计的分辨率。如果屏幕是480x272,设计师给了960x544的图,直接缩到一半。别犹豫。
  3. 去冗余Alpha:很多PNG的Alpha通道是全白的(完全不透明)。这种情况下,可以去掉Alpha通道,转成RGB565。
  4. 量化颜色:对于L8格式,用工具(如pngquant)把颜色数降到256色以内。调色板优化得好,视觉损失几乎看不出来。

我的习惯:我会在项目里建一个“预处理脚本”。每次设计师更新资源,我跑一遍脚本,自动完成降位深、缩分辨率、量化颜色。省时省力,还不会漏掉哪张图。

3.6 格式选择决策流程

说了这么多,到底怎么选?我画了一张流程图,帮你快速决策。

图像格式选择决策流程 原始图像 是否需要透明通道? 是 否 仅需透明信息? (阴影、遮罩) 是 使用 A4 否 颜色数 ≤ 256? (图标、简单插图) 是 使用 L8 否 评估内容复杂度 大面积纯色或简单图形? 是 否 使用 RLE 使用 RGB565 提示:如果图像是照片或高精度渐变,直接使用RGB565或RGBA8888,不要强行压缩。

3.7 实战:用ImageMagick做批量预处理

说了这么多理论,来点实际的。我常用ImageMagick做批量预处理。下面这个脚本,能一键把目录下所有PNG转成最适合的格式。

#!/bin/bash
# 批量图像预处理脚本
# 用法:./preprocess_images.sh input_dir output_dir

INPUT_DIR=$1
OUTPUT_DIR=$2

mkdir -p $OUTPUT_DIR

for file in $INPUT_DIR/*.png; do
    filename=$(basename "$file")
    name="${filename%.*}"
    
    # 1. 缩放到目标分辨率(假设屏幕是480x272)
    convert "$file" -resize 480x272\> "$OUTPUT_DIR/${name}_resized.png"
    
    # 2. 检查颜色数,决定是否转L8
    colors=$(identify -format "%k" "$OUTPUT_DIR/${name}_resized.png")
    if [ $colors -le 256 ]; then
        # 转L8
        convert "$OUTPUT_DIR/${name}_resized.png" -colors 256 "$OUTPUT_DIR/${name}_L8.png"
        echo "$filename: 转L8成功"
    else
        # 转RGB565
        convert "$OUTPUT_DIR/${name}_resized.png" -depth 16 "$OUTPUT_DIR/${name}_RGB565.png"
        echo "$filename: 颜色数过多,转RGB565"
    fi
done

小技巧:你可以把这个脚本集成到CI/CD流程里。每次设计师提交新资源,自动触发预处理。这样,开发人员永远拿到的是“瘦身版”资源,不会有人手滑把大图塞进去。

3.8 总结:省内存,从选对格式开始

图像资源压缩,说白了就是“用最少的位数,表达最多的信息”。L8、A4、RLE,各有各的适用场景。选对了,内存占用直接砍半甚至更多。选错了,不仅没省,还可能影响显示效果。

我个人习惯,在项目初期就定好图像资源规范。哪些用L8,哪些用A4,哪些用RLE,写清楚。然后配合预处理脚本,自动化执行。这样,整个团队都能受益。

嗯,这一章就到这里。记住,下一张图放进去之前,先问问自己:“它真的需要32位吗?”