Bar*_*sen 6 c++ color-picker colors 16-bit
我正在开发一个带TFT触摸屏的项目,这个屏幕上有一个包含的库.但经过一些阅读,我仍然没有得到什么.在库中有一些关于颜色的定义:
/* some RGB color definitions */
#define Black 0x0000 /* 0, 0, 0 */
#define Navy 0x000F /* 0, 0, 128 */
#define DarkGreen 0x03E0 /* 0, 128, 0 */
#define DarkCyan 0x03EF /* 0, 128, 128 */
#define Maroon 0x7800 /* 128, 0, 0 */
#define Purple 0x780F /* 128, 0, 128 */
#define Olive 0x7BE0 /* 128, 128, 0 */
#define LightGrey 0xC618 /* 192, 192, 192 */
#define DarkGrey 0x7BEF /* 128, 128, 128 */
#define Blue 0x001F /* 0, 0, 255 */
#define Green 0x07E0 /* 0, 255, 0 */
#define Cyan 0x07FF /* 0, 255, 255 */
#define Red 0xF800 /* 255, 0, 0 */
#define Magenta 0xF81F /* 255, 0, 255 */
#define Yellow 0xFFE0 /* 255, 255, 0 */
#define White 0xFFFF /* 255, 255, 255 */
#define Orange 0xFD20 /* 255, 165, 0 */
#define GreenYellow 0xAFE5 /* 173, 255, 47 */
#define Pink 0xF81F
Run Code Online (Sandbox Code Playgroud)
这些是16位颜色.但他们如何从:0,128,128(深青色)到0x03EF.我的意思是,你如何将16位颜色转换为uint16?这不需要在代码中有一个anwser,因为我只想在库中添加一些collors.链接到在线转换器(我找不到)也没关系:)
谢谢
您需要知道显示器的确切格式,仅“16 位”是不够的。
有 RGB555,其中三个组件中的每一个都有 5 位。这将总色彩空间降低到只有 32,768 种颜色,浪费了一点,但管理起来非常简单,因为每个组件都有相同数量的色调。
还有RGB565,其中绿色成分被赋予6位(因为人眼对绿色更敏感)。这可能是您使用的格式,因为“深绿色”示例是0x03e0二进制文件中的0b0000 0011 1110 0000. 由于那里有 6 位设置为 1,我想这是绿色组件的总分配并显示它的最大值。
就是这样,然后(用空格分隔每四位并重新使用假想0b前缀):
0bRRRR RGGG GGGB BBBB
Run Code Online (Sandbox Code Playgroud)
当然,位顺序也可以不同,就字而言。
将三元组数字转换为位压缩字的任务在具有位操作运算符的典型编程语言中很容易完成。
在 C 中,它通常在宏中完成,但我们也可以拥有一个函数:
#include <stdint.h>
uint16_t rgb565_from_triplet(uint8_t red, uint8_t green, uint8_t blue)
{
red >>= 3;
green >>= 2;
blue >>= 3;
return (red << 11) | (green << 5) | blue;
}
Run Code Online (Sandbox Code Playgroud)
请注意,以上假设组件具有完整的 8 位精度,因此组件的最大强度为 255,而不是您的示例中的 128。如果色彩空间确实使用 7 位组件,则需要进行一些额外的缩放。
从这些可以很容易地找出公式:
#define Red 0xF800 /* 255, 0, 0 */
#define Magenta 0xF81F /* 255, 0, 255 */
#define Yellow 0xFFE0 /* 255, 255, 0 */
Run Code Online (Sandbox Code Playgroud)
F800设置了5个MSB位,FFE0未设置5个LSB.0xF81F显然有5个LSB和5个MSB的设置,证明格式为RGB565.
将值173转换为红色的公式并不像它看起来那么简单 - 您不能简单地删除3个最低有效位,而是必须线性插值以使255对应于31(或绿色255对应于63).
NewValue = (31 * old_value) / 255;
Run Code Online (Sandbox Code Playgroud)
(这仍然只是一个截断的部门 - 可能需要适当的舍入)
适当的舍入和缩放:
Uint16_value = (((31*(red+4))/255)<<11) |
(((63*(green+2))/255)<<5) |
((31*(blue+4))/255);
Run Code Online (Sandbox Code Playgroud)
编辑添加括号,由JasonD提供有用的建议.