最近更新于 2024-01-11 21:08

刚上手一块 TFT 屏,使用 Arduino 控制,在看 Adafruit-ST7735-Library 库的 demo 时,发现里面用的颜色值很奇怪,并不是一般用的每种基色取 0-255 的 RGB,然后才注意到注释写了 “565”
file

以前没用过这种颜色模式,查了一下就懂了。
一般用的 RGB 值每种基色是 256 个级别,也就是 2^8,每个基色是一个 8 位数,所以称为 RGB888,三个基色共 24 位,也就是 24 位真彩色。
这个 565 就是 R、G、B 位数分别是 5、6、5,总共 16 位,即 16 位真彩色。

要进行颜色转换的话,首先要从 RGB888 的颜色值中分别提取出三个基色的颜色值。最左边的 8 位是 R,中间的 8 位是 G,最右边的 8 位是 B。先用与运算就可以将对应基色外的数值清零,再位移取出来。

    uint8_t r8 = (rgb888 & 0xFF0000) >> 16;
    uint8_t g8 = (rgb888 & 0x00FF00) >> 8;
    uint8_t b8 = (rgb888 & 0x0000FF);

此时取出来的每种基色是 8 位的,R 和 B 要 5 位,所以右移 3 位,G 要 6 位,所以右移 2 位。R 放到最左边 5 位,所以左移 5 位,G 放在中间 6 位,所以左移 5 位,B 放在最右边 5 位,无需额外处理。

uint8_t r5 = ((r >> 3) << 11);
uint8_t r6 = ((g >> 2) << 5);
uint8_t r5 = (b >> 3);

最后用或运算拼在一起就行,下面是最终的代码:

// 参数传入一个十六进制颜色值使用该函数,比如
// 红色 0xFF0000
// 绿色 0x00FF00
// 蓝色 0x0000FF
uint16_t rgb888_to_565 (uint32_t rgb888, bool reverse = false)
{
    uint8_t r = (rgb888 & 0xFF0000) >> 16;
    uint8_t g = (rgb888 & 0x00FF00) >> 8;
    uint8_t b = (rgb888 & 0x0000FF);

    if (reverse)
    {
        return ((b >> 3) << 11) |
                ((g >> 2) << 5) |
                (r >> 3);
    }

    return ((r >> 3) << 11) |
            ((g >> 2) << 5) |
            (b >> 3);
}

// 如果分别传入基色使用该函数,比如
// 红色 255, 0, 0
// 绿色 0, 255, 0
// 蓝色 0, 0, 255
uint16_t rgb888_to_565(uint8_t r, uint8_t g, uint8_t b, bool reverse = false)
{
    if (reverse)
    {
        return ((b >> 3) << 11) |
                ((g >> 2) << 5) |
                (r >> 3);
    }

    return ((r >> 3) << 11) |
            ((g >> 2) << 5) |
            (b >> 3);
}

我在实际操作的时候遇到一个问题,如果初始化的时候参数使用 INITR_GREENTAB,颜色设置就是 RGB,但是在我使用的屏幕上出现了显示偏移的问题,然后看到 demo 的注释说如果是有偏移的屏幕,参数要使用 INITR_GREENTAB。然后偏移确实解决了,但是颜色设置又变成了 BGR,也就是顺序反了。因此上面的函数我多加了一个参数控制,默认值 false 就是返回 RGB,如果传入参数 true,则返回 BGR,这样两种颜色顺序都能兼顾。
file

常用颜色 RGB 值:

  • 黑色 0,0,0 0x000000
  • 白色 255,255,255 0xFFFFFF
  • 蓝色 0,0,255 0x0000FF
  • 紫色 255,0,255, 0xFF00FF
  • 象牙黑 88,87,86 0x666666
  • 天蓝灰 202,235,216 0xF0FFFF
  • 冷灰 128,138,135 0x808A87
  • 灰色 192,192,192 0xCCCCCC
  • 暖灰 128,118,105 0x808069
  • 象牙灰 251,255,242 0xFAFFF0
  • 石板灰 118,128,105 0xE6E6E6
  • 亚麻灰 250,240,230 0xFAF0E6
  • 白烟灰 245,245,245 0xF5F5F5
  • 杏仁灰 255,235,205 0xFFFFCD
  • 蛋壳灰 252,230,202 0xFCE6C9
  • 贝壳灰 255,245,238 0xFFF5EE
  • 红色 255,0,0 0xFF0000
  • 黄色 255,255,0 0xFFFF00
  • 镉红 227,23,13 0xE3170D
  • 镉黄 255,153,18 0xFF9912
  • 砖红 156,102,31 0x9C661F
  • 香蕉黄 227,207,87 0xE3CF57
  • 珊瑚红 255,127,80 0xFF7F50
  • 金黄 255,215,0 0xFFD700
  • 番茄红 255,99,71 0xFF6347
  • 肉黄 255,125,64 0xFF7D40
  • 粉红 255,192,203 0xFFC0CB
  • 粉黄 255,227,132 0xFFE384
  • 印度红 176,23,31 0xB0171F
  • 橘黄 255,128,0 0xFF8000
  • 深红 255,0,255 0xFF00FF
  • 萝卜黄 237,145,33 0xED9121
  • 黑红 116,0,0 0x990033
  • 黑黄 85,102,0 0x8B864E
  • 绿色 0,255,0 0x00FF00
  • 棕色 128,42,42 0x802A2A
  • 青色 0,255,255 0x00FFFF
  • 土色 199,97,20 0xC76114