2023年7月

先说结论:这个屏幕的颜色编码不是传统的rgb565,经过计算是bBgrG33253,3个蓝色低位,3个蓝色高位,2个绿色低位,5个红色位,3个绿色高位。

最近开发界面的时候想要让文字展示的时候不要那么突兀,也就是要将底色和原本的背景色显示成一样的,但是背景是直接用图片展示的,然而文字显示需要用lcd.draw_string()方法,这个方法内默认要传两个颜色参数,一个是文字颜色,一个是底色,传图片的时候完全不需要考虑rgb码,图片字节流丢进去全交给方法处理就行了,但是文字的不一样,需要指定一个色码。
不用不知道,一用发现挺有讲究,官方文档介绍此处可以传三种格式,一个是自带的常量,例如lcd.WHITE就是白色;另一种是rgb565,一会细说;还有一个是rgb888元组,经过测试并不能用,可能是屏幕不支持吧,这个屏幕是65536色的,也就是说颜色有16位,符合rgb565,rgb888的24位色不能显示。
然后就要讲到这个rgb565的坑了,按照我在网上搜的rgb565应该是如下图所示:
20181121131550287.png
但是按照这个格式转换的rgb颜色值还是与预期不符,于是我开始一点一点测试r、g、b三个颜色分别对应哪个片段,然后发现他们按照六个蓝两个绿五个红三个绿排列,就很奇怪,为什么要把绿色像素分开,我理解可能是要分开高位低位,前八位后八位方便硬件处理,后三位的绿色是绿色的高位,前两位是低位,捋完这个我以为大功告成了,做了一个测试,将一个rgb元组转换成了这个bgrg6253,找了个数一测,还是不一样,大概对比了一下颜色跟数字,我得出一个结论,蓝色的六位不是按正常顺序排列的六位,果然,经过单独的颜色测试,蓝色是前三位低,后三位高,最终得到颜色转换代码

def rgb888_to_rgb565(rgb888):
    # 缩减位数
    red = (rgb888 >> 16) & 0xFF
    green = (rgb888 >> 8) & 0xFF
    blue = rgb888 & 0xFF

    # 转换成bgrg6253
    blue6253 = (blue>>2) & 0x3f
    green6253 = (green>>3)& 0x1f
    red6253 = (red>>3) & 0x1f

    # 蓝色3低位,蓝色3高位,绿色2低位,红色5位,绿色3高位
    bgrg6253 = ((blue6253&0x07)<<13)|((blue6253&0x38)<<7)|((green6253&0x3)<<8)|(red6253<<3)|(green6253&0x1c)>>2

    return bgrg6253


rgb888_value = 0xffffff  # 需要转换的rgb16进制表示
bgrg6253_result = rgb888_to_rgb565(rgb888_value)

print("RGB888:", hex(rgb888_value))
print("bgrg6253:",hex(bgrg6253_result))