4、图像资源优化:压缩图片格式、使用纹理集、减少图片尺寸
图像资源,往往是 TouchGFX 项目里最吃内存的「大户」。我见过不少团队,代码逻辑写得漂漂亮亮,结果一跑起来,帧率死活上不去。查到最后,问题都出在图片上。
说白了,一张 800×480 的 ARGB8888 背景图,就要吃掉 1.5MB 的 RAM。你想想看,如果你的 MCU 只有 8MB 外部 RAM,光放几张图就快满了。所以,图像资源优化,是性能调优里性价比最高的一环。
核心原则:在保证视觉效果可接受的前提下,尽可能降低每张图片的内存占用和加载带宽。
4.1 图片格式的选择:L8、RGB565 vs ARGB8888
TouchGFX 支持多种图片格式。选对了格式,内存占用能直接砍掉一半甚至更多。我习惯把格式选择分成三类:
| 格式 | 每像素位数 | 支持透明 | 适用场景 | 内存占用(800×480) |
|---|---|---|---|---|
| ARGB8888 | 32 bpp | 是(8位 Alpha) | 照片、渐变、需要半透明效果的图片 | 1.5 MB |
| RGB565 | 16 bpp | 否 | 不透明图标、按钮、纯色背景 | 768 KB |
| L8 | 8 bpp | 支持(调色板中定义) | 颜色数少的界面元素、小图标、文字 | 384 KB |
看到这个对比,你应该明白了。ARGB8888 虽然画质最好,但代价也最大。RGB565 去掉了 Alpha 通道,颜色深度从 8bit 降到 5-6bit,人眼其实很难察觉差异。L8 则更进一步,它用一张 256 色的调色板来映射颜色,适合颜色种类少的图片。
我的习惯:背景图、照片类用 RGB565;图标、按钮用 L8;只有需要半透明叠加效果时才用 ARGB8888。这样组合下来,整体内存能省 40%~60%。
我在项目中遇到过一件事。有个客户做智能家居面板,界面里用了大量渐变色背景。他们全部用了 ARGB8888,结果 8MB 的 RAM 被图片占掉 6MB,动画一多就卡。后来我把背景图转成 RGB565,图标转成 L8,内存直接降到 3.2MB,帧率从 25fps 飙到了 55fps。
4.2 纹理集:把零散图片打包
纹理集,说白了就是把多张小图拼成一张大图。为什么要这么做?因为 TouchGFX 在渲染时,每切换一张图片,GPU 就要做一次纹理绑定。绑定次数多了,性能就下来了。
纹理集的好处有两个:
- 减少纹理切换:一次绑定,渲染整张纹理集里的所有元素。
- 节省内存:多张小图各自有对齐开销,拼在一起能减少碎片。
我建议你把项目中所有图标、按钮、小装饰图都整理出来。按使用频率分组,把同一屏上出现的元素尽量放在一张纹理集里。TouchGFX 的 Image 控件支持从纹理集中裁剪子区域,你只需要在 Designer 里设置好坐标就行。
注意:纹理集不要做得太大。如果一张纹理集超过 1024×1024,加载时间反而会增加。我一般控制在 512×512 以内,每张纹理集放 20~30 个小图标。
我曾经帮一个团队优化过他们的 HMI 项目。他们用了 80 多张小图标,每张都是独立的 PNG。我帮他们打包成 4 张 512×512 的纹理集,纹理绑定次数从 80 次降到了 4 次,界面切换的卡顿感直接消失了。
4.3 减少图片尺寸:别用大图做小事
这个道理很简单,但很多人会忽略。你的屏幕分辨率是 480×272,但设计师给的背景图是 1920×1080。TouchGFX 虽然会缩放显示,但图片在内存里还是按原始尺寸加载的。一张 1920×1080 的 ARGB8888 图片,要吃掉 8MB 内存。而缩放到 480×272 后,只需要 640KB。
所以,我的建议是:
- 按屏幕分辨率裁剪:图片尺寸不要超过屏幕尺寸。如果屏幕是 800×480,背景图就做成 800×480。
- 按实际显示区域裁剪:如果图片只显示在屏幕的 1/4 区域,就只裁剪那一部分。
- 使用 TouchGFX 的 Image Scaling:如果必须缩放,尽量在 PC 端预处理,不要在运行时让 MCU 做缩放。
小技巧:在 TouchGFX Designer 里,你可以直接设置 Image 控件的宽度和高度。但注意,这只是在显示时缩放,内存里还是原始大小。真正的优化,是在图片导入前就把它缩到目标尺寸。
我记得有个项目,客户抱怨界面启动太慢。我一看,背景图是 1280×720 的 ARGB8888,而屏幕只有 480×272。我把图片缩到 480×272 并转成 RGB565,启动时间从 3.2 秒降到了 0.8 秒。嗯,这就是大图小用的代价。
4.4 知识体系总览
下面这张图,把图像资源优化的核心逻辑串起来了。你可以对照着看,自己的项目在哪个环节还有优化空间。
4.5 避坑指南
最后,分享几个我踩过的坑:
- 不要迷信 PNG 压缩:PNG 是文件压缩格式,不是内存格式。TouchGFX 在运行时会把 PNG 解压成原始像素数据。文件小不代表内存小。
- L8 调色板要谨慎:如果图片颜色数超过 256 种,L8 会出现明显的色块。我建议用 Photoshop 或 GIMP 先把图片颜色数降到 256 色以下,再导入。
- 纹理集更新要小心:如果纹理集里的某个图标需要动态更新,整个纹理集都要重新加载。这种情况下,把动态图标单独放一张纹理集。
我曾经踩过的坑:有一次,我把所有图标都塞进一张 1024×1024 的纹理集里。结果有一个图标需要根据用户状态变色,我不得不每次更新都重新加载整张纹理集。后来我把动态图标单独拿出来,问题就解决了。
图像资源优化,说白了就是「斤斤计较」。每张图片省几十 KB,几十张图片加起来,就是几 MB 的差距。而这些省下来的内存,可以留给更复杂的动画、更多的页面、更流畅的交互。嗯,这就是优化的价值。