将颜色格式从 RGB565 更改为 RGB888 涉及位扩展和重新排列颜色分量。以下是详细步骤和示例代码:
转换原理
RGB565 格式:
- 每个像素占用 16 位(2字节)
- 红色(R)占高 5位,绿色(G)占中间 6位,蓝色(B)占低 5位
- 像素布局:
RRRRR GGGGGG BBBBB
RGB888 格式:
- 每个像素占用 24 位(3字节)
- R、G、B 各占 8位
- 存储顺序通常为
R, G, B(可调整)
转换公式:
R8 = (R5 << 3) | (R5 >> 2) (5位 → 8位)
G8 = (G6 << 2) | (G6 >> 4) (6位 → 8位)
B8 = (B5 << 3) | (B5 >> 2) (5位 → 8位)
C语言实现
#include
// 单像素转换函数
void rgb565_to_rgb888(uint16_t rgb565, uint8_t *r8, uint8_t *g8, uint8_t *b8) {
// 提取RGB565分量
uint8_t r5 = (rgb565 >> 11) & 0x1F; // 高5位(红色)
uint8_t g6 = (rgb565 >> 5) & 0x3F; // 中间6位(绿色)
uint8_t b5 = rgb565 & 0x1F; // 低5位(蓝色)
// 扩展到RGB888
*r8 = (r5 << 3) | (r5 >> 2); // 5位→8位
*g8 = (g6 << 2) | (g6 >> 4); // 6位→8位
*b8 = (b5 << 3) | (b5 >> 2); // 5位→8位
}
// 批量转换(示例)
void convert_image(uint16_t *src, uint8_t *dst, uint32_t pixel_count) {
for (uint32_t i = 0; i < pixel_count; i++) {
uint8_t r, g, b;
rgb565_to_rgb888(src[i], &r, &g, &b);
// 存储顺序:R, G, B
*dst++ = r;
*dst++ = g;
*dst++ = b;
}
}
优化(查表法)
预先计算转换表可提高速度:
static uint8_t r5_to_r8[32];
static uint8_t g6_to_g8[64];
static uint8_t b5_to_b8[32];
void init_tables() {
for (int i = 0; i < 32; i++) {
r5_to_r8[i] = (i << 3) | (i >> 2); // R5→R8
b5_to_b8[i] = (i << 3) | (i >> 2); // B5→B8
}
for (int i = 0; i < 64; i++) {
g6_to_g8[i] = (i << 2) | (i >> 4); // G6→G8
}
}
void fast_convert(uint16_t *src, uint8_t *dst, uint32_t n) {
while (n--) {
uint16_t pixel = *src++;
*dst++ = r5_to_r8[(pixel >> 11) & 0x1F]; // R分量
*dst++ = g6_to_g8[(pixel >> 5) & 0x3F]; // G分量
*dst++ = b5_to_b8[pixel & 0x1F]; // B分量
}
}
关键点
分量提取:
R5 = (rgb565 >> 11) & 0x1F
G6 = (rgb565 >> 5) & 0x3F
B5 = rgb565 & 0x1F
位扩展逻辑:
- 通过位移和位或操作填充低位,例如:
R8 = (R5 << 3) | (R5 >> 2)
相当于复制高位到低位(0b10111 → 0b10111101)。
内存布局:
- RGB888 输出顺序可按需调整(如改为
BGR 需调整赋值顺序)。
性能建议
- 使用查表法(LUT)减少实时计算。
- 启用编译器优化(如
-O3)。
- 内存充足时可预生成所有像素映射表(64KB → 192KB表)。
通过以上步骤,即可高效地将N9H20的RGB565图像转换为RGB888格式。