2、图像基础与格式选择:位图与矢量图、常见格式对比、有损与无损压缩原理

做界面移植,第一个绕不开的问题就是:图片到底该怎么选?

我见过不少项目,界面移植到嵌入式设备上,跑起来卡顿、内存爆掉,最后查下来,问题往往出在图片格式上。说白了,选错格式,后面再怎么优化都是白费力气。

2.1 位图 vs 矢量图:先搞清楚你手里拿的是什么

图像分两大类:位图和矢量图。这个区别,我建议你刻在脑子里。

  • 位图(Bitmap):由像素点阵组成。每个像素记录颜色值。放大到一定程度,就会看到马赛克。照片、截图、复杂纹理,都是位图。
  • 矢量图(Vector):由数学公式描述。记录的是点、线、面、颜色填充规则。放大多少倍都不会失真。图标、Logo、字体、简单图形,适合用矢量。

核心结论:界面移植中,图标、按钮、装饰性元素尽量用矢量图(SVG);照片、背景图、复杂渐变只能用位图。这个原则能帮你省掉至少 30% 的存储空间。

我在一个智能手表项目里遇到过这种情况:设计师给了全套 PNG 图标,每个 48x48,一套下来 200 多个文件。我让他重新导出成 SVG,体积直接缩到原来的 1/10,而且在不同屏幕尺寸下自动适配,不用再切图了。

2.2 常见位图格式对比:PNG / JPEG / WebP / AVIF

位图格式很多,但界面移植场景下,你主要跟这四种打交道。我整理了一张对比表,你直接拿去用。

格式 压缩类型 透明通道 典型场景 我个人的建议
PNG 无损 支持(Alpha) 图标、UI 元素、需要透明底的图片 兼容性最好,但体积偏大。嵌入式设备上慎用大图。
JPEG 有损 不支持 照片、复杂背景图、不需要透明的场景 压缩率高,但边缘会有振铃效应。不适合文字和线条。
WebP 有损/无损 支持 Web 界面、移动端、嵌入式 HMI 我目前的主力格式。体积比 PNG 小 30%~50%,质量几乎看不出区别。
AVIF 有损/无损 支持 新一代压缩标准,高压缩比场景 压缩率比 WebP 还高 20% 左右,但解码开销大。低端 MCU 上慎用。

我的经验:如果你的目标平台是 Cortex-M 系列或更低性能的 MCU,优先用 PNG 或 JPEG。WebP 和 AVIF 的解码库比较大,可能撑爆你的 Flash 空间。如果是 Linux 或 Android 平台,放心上 WebP。

2.3 有损压缩 vs 无损压缩:到底差在哪?

这个问题,我当年刚入行时也搞混过。后来自己动手写了一个简单的图像压缩工具,才算真正弄明白。

无损压缩

原理:利用数据冗余。比如一张纯色背景的图,相邻像素颜色一样,那就只存一次颜色值,再记个重复次数。PNG 用的就是这种思路。

  • 解压后跟原图一模一样,像素值完全不变。
  • 适合图标、文字、医疗影像、任何不能容忍失真的场景。
  • 压缩率有限,一般 2:1 到 5:1 就差不多了。

有损压缩

原理:丢弃人眼不敏感的信息。比如 JPEG 会把高频细节模糊掉,因为人眼对亮度变化敏感,对颜色变化不敏感。它先把图像从 RGB 转到 YCbCr 色彩空间,然后对色度通道做降采样,再对亮度通道做离散余弦变换(DCT),最后量化掉那些不重要的系数。

  • 解压后跟原图有差异,但人眼可能看不出来。
  • 适合照片、背景图、视频帧。
  • 压缩率可以做到 10:1 甚至 20:1,质量还能接受。

避坑指南:我曾经在一个医疗设备界面移植项目里,用 JPEG 压缩了 X 光片的缩略图。结果医生投诉说边缘有伪影,影响诊断。从那以后,凡是涉及医疗、工业检测、文字识别的场景,我坚决只用无损格式。

2.4 知识体系:图像格式选择决策流程

下面这张图,是我自己总结的。每次做界面移植,我都会过一遍这个流程。

图像格式选择决策流程 图像格式选择决策流程 原始图像 是否需要透明通道? 是 否 PNG / WebP JPEG / WebP / AVIF 平台解码性能? 平台解码性能? 低性能 → PNG 低性能 → JPEG 高性能 → WebP 高性能 → WebP/AVIF 说明: 低性能平台指 Cortex-M 系列或同等 MCU 高性能平台指 Linux/Android 或 Cortex-A 系列

2.5 实际项目中的选择策略

光讲理论不够,我拿几个真实场景给你拆解一下。

场景一:智能家居面板(Cortex-M4,512KB Flash)

  • 图标:全部用 SVG 矢量图,运行时渲染成位图。或者用 PNG-8(256色),体积小。
  • 背景图:用 JPEG,质量设为 80%,人眼看不出区别。
  • 按钮状态图:用 PNG-24,保留透明通道。
  • 避坑:不要用 WebP,解码库太大,Flash 装不下。

场景二:车载中控屏(Linux + Qt,2GB RAM)

  • 图标:SVG 直接加载,Qt 原生支持。
  • 导航地图瓦片:用 WebP 有损压缩,质量 90%,比 PNG 小 40%。
  • 启动画面:用 JPEG,质量 85%,解码速度快。
  • 避坑:注意 WebP 的编码参数,alpha 通道质量别设太低,否则边缘会有锯齿。

场景三:智能手表(Cortex-M0+,128KB Flash,64KB RAM)

  • 所有图像:全部用 1-bit 或 2-bit 位图,自己写 RLE 压缩。
  • 字体:用像素字体,不加载任何图片格式。
  • 避坑:这种资源下,别想什么 WebP 了。老老实实自己写压缩算法。

一个实用技巧:我习惯在项目初期,先拿目标平台跑一遍解码性能测试。找一张典型的界面截图,分别导出为 PNG、JPEG、WebP,然后测量解码时间和内存占用。数据说话,比拍脑袋靠谱得多。

2.6 本章小结

图像格式选择,说白了就是一场权衡:体积、质量、解码速度、平台能力,四者之间找平衡点。

  • 位图 vs 矢量图:矢量优先,位图兜底。
  • 有损 vs 无损:能接受失真就上有损,不能就上无损。
  • 格式选择:PNG 保底,WebP 主力,AVIF 看平台,JPEG 留给照片。

记住一点:没有最好的格式,只有最适合你当前平台的格式。动手测一测,比看一百篇对比文章都管用。