图像数据基础:位深度、调色板与 RGB 格式
做嵌入式 GUI,说白了就是在跟「内存」和「带宽」这两个老朋友打交道。图像数据怎么存、存多大,直接决定了你的界面能不能跑起来、跑得顺不顺。这一章,我就带你把这些基础概念彻底理清楚。
位深度:一个像素到底占多少比特?
位深度(Bit Depth)这个概念,我习惯把它理解为「每个像素用多少比特来描述」。你想想看,一个像素如果只有 1 比特,那它只能表示黑或白,也就是 2 种颜色。如果是 8 比特,那就是 2^8 = 256 种颜色。
常见的位深度有这么几种:
- 1 位:黑白图,每个像素 1/8 字节。适合做图标、字体掩码。
- 4 位:16 色,通常配合调色板使用。我在做低端彩屏项目时常用。
- 8 位:256 色,可以调色板也可以直接灰度。经典的小尺寸 LCD 方案。
- 16 位:RGB565,嵌入式 GUI 的「万金油」。
- 24 位:RGB888,真彩色,但存储开销大。
- 32 位:ARGB8888,带透明度,现代 GUI 的标配。
核心公式:图像大小(字节)= 宽度 × 高度 × 位深度 / 8
举个例子:一张 320×240 的 RGB565 图片,大小 = 320 × 240 × 16 / 8 = 153,600 字节 ≈ 150 KB。
嗯,这里要注意:位深度越高,色彩越丰富,但存储和传输压力也越大。我见过不少新手一上来就用 ARGB8888,结果内存爆了还不知道怎么回事。
调色板:用少量颜色实现丰富效果
调色板(Palette)是个好东西。它的原理很简单:建立一个颜色查找表,像素值存的是索引,而不是颜色本身。
举个例子,8 位调色板模式:
- 调色板表:256 个颜色条目,每个条目 4 字节(RGBA),总共 1 KB。
- 像素数据:每个像素 1 字节,存的是索引值。
- 最终显示时,通过索引查表得到真实颜色。
这样做的好处很明显——存储大幅减少。一张 320×240 的 8 位调色板图片,像素数据只有 76.8 KB,加上调色板 1 KB,总共不到 78 KB。而同样的分辨率用 RGB565 要 150 KB,ARGB8888 更是要 300 KB。
我的经验:调色板特别适合 UI 中的图标、按钮、背景纹理。这些元素颜色种类通常不多,用调色板能省下一大半空间。我曾经在一个 512 KB Flash 的项目里,靠调色板把整套 UI 图片从 400 KB 压缩到了 180 KB。
RGB565 与 ARGB8888 格式对比
这两种格式是嵌入式 GUI 里最常用的。我分别说说它们的特点。
RGB565
每个像素 16 位:红色 5 位、绿色 6 位、蓝色 5 位。为什么绿色多 1 位?因为人眼对绿色最敏感,多 1 位能提升视觉质量。
- 优点:存储小,传输快,适合低端 MCU。
- 缺点:不支持透明度,色彩精度有限(总共 65,536 色)。
- 典型应用:STM32F4 + 小尺寸 LCD,不带透明效果的 UI。
ARGB8888
每个像素 32 位:Alpha 透明度 8 位、红色 8 位、绿色 8 位、蓝色 8 位。支持 256 级透明度,色彩达到 16,777,216 色。
- 优点:真彩色 + 透明混合,视觉效果一流。
- 缺点:存储是 RGB565 的两倍,对内存带宽要求高。
- 典型应用:带 Alpha 混合的图标、弹窗阴影、复杂动画。
| 对比项 | RGB565 | ARGB8888 |
|---|---|---|
| 位深度 | 16 位 | 32 位 |
| 颜色数 | 65,536 | 16,777,216 |
| 透明度 | 不支持 | 支持 256 级 |
| 320×240 大小 | 150 KB | 300 KB |
| MCU 友好度 | 高 | 低 |
| 适用场景 | 简单 UI、低端硬件 | 复杂 UI、高端硬件 |
避坑指南:我曾经在一个项目里,为了省事把所有图片都转成了 ARGB8888。结果在 STM32F429 上跑起来,刷屏速度只有 15 FPS,内存也差点爆了。后来把不需要透明的图片改成 RGB565,速度直接翻倍到 30 FPS。所以,不要盲目追求高色深,根据实际需求选择。
存储影响分析
图像数据对存储的影响,主要体现在三个方面:
- Flash 占用:图片资源烧录到 Flash 中,决定了你能放多少张图。
- RAM 占用:解码后的帧缓冲区(Frame Buffer)需要常驻 RAM。
- 传输带宽:从 Flash 读到 RAM,或者从 RAM 刷到 LCD,都需要带宽。
我习惯用一个简单的公式来估算:
// 帧缓冲区大小计算
uint32_t fb_size = width * height * bytes_per_pixel;
// 举例:320x240 分辨率
// RGB565: 320 * 240 * 2 = 153,600 字节
// ARGB8888: 320 * 240 * 4 = 307,200 字节
你看,同样的分辨率,ARGB8888 的帧缓冲区是 RGB565 的两倍。如果你的 MCU 只有 256 KB RAM,用 ARGB8888 的话,一个帧缓冲区就占掉 300 KB,根本放不下。这时候要么降分辨率,要么换格式。
实战建议:
- RAM < 256 KB:优先用 RGB565 或调色板模式。
- RAM 256 KB ~ 512 KB:混合使用,关键元素用 ARGB8888,背景用 RGB565。
- RAM > 512 KB:可以全用 ARGB8888,但要注意带宽。
知识体系结构图
下面这张图,我把本章的核心知识点串了起来,方便你理解它们之间的关系。
小结
这一章我们聊了位深度、调色板、RGB565 和 ARGB8888 这些基础概念。说白了,它们都是在「色彩质量」和「存储开销」之间做权衡。我个人习惯在做项目选型时,先看硬件资源,再定图像格式,最后才动手做 UI 设计。顺序搞反了,后面返工的成本会很高。