我正在开发一个带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
这些是16位颜色。但他们如何从:0,128,128(深青色)到0x03EF。我的意思是,你如何将16位颜色转换为uint16?这不需要在代码中有一个anwser,因为我只想在库中添加一些collors。链接到在线转换器(我找不到)也没关系:)
谢谢
答案 0 :(得分:5)
从这些人可以很容易地找出公式:
#define Red 0xF800 /* 255, 0, 0 */
#define Magenta 0xF81F /* 255, 0, 255 */
#define Yellow 0xFFE0 /* 255, 255, 0 */
F800设置了5个MSB位,FFE0未设置5个LSB。 0xF81F显然有5个LSB和5个MSB的设置,证明格式为RGB565。
将值173转换为红色的公式并不像它看起来那么简单 - 你不能简单地删除3个最低有效位,而是必须线性插值使255对应31(或绿色255)对应于63)。
NewValue = (31 * old_value) / 255;
(这仍然只是一个截断分区 - 可能需要进行适当的舍入)
适当的舍入和缩放:
Uint16_value = (((31*(red+4))/255)<<11) |
(((63*(green+2))/255)<<5) |
((31*(blue+4))/255);
编辑在JasonD的帮助下添加了括号。
答案 1 :(得分:4)
您需要知道显示器的确切格式,仅“16位”是不够的。
有RGB555,其中三个组件中的每一个都获得5位。这会将总色彩空间降低到32,768种颜色,浪费一点但管理起来非常简单,因为每个组件的色调数量都相同。
还有RGB565,其中绿色成分为6位(因为人眼对绿色更敏感)。这可能是您所拥有的格式,因为“深绿色”示例为0x03e0
,二进制为0b0000 0011 1110 0000
。由于那里有6位设置为1,我猜这是绿色组件的总分配并显示它的最大值。
就像这样,然后(用空格分隔每四位并重新使用虚构的0b
前缀):
0bRRRR RGGG GGGB BBBB
当然,在单词中,位顺序也可能不同。
在具有位操作算子的典型编程语言中,将三重数字转换为位打包字的任务非常容易。
在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;
}
请注意,上面假设组件的完整8位精度,因此组件的最大强度为255,而不是示例中的128。如果颜色空间确实使用7位组件,则需要进行一些额外的缩放。
答案 2 :(得分:4)
看起来你正在使用RGB565,前5位用于红色,然后6位用于绿色,然后5位用于蓝色。
你应该用0xF800屏蔽并向右移11位以获得红色分量(或移位8位以获得0-255的值)。 屏蔽0x07E0并向右移5位以获得绿色分量(或3以获得0-255值)。 使用0x001F进行掩码以获得蓝色分量(并向左移3位以获得0-255)。
答案 3 :(得分:3)
您的颜色为565格式。如果你用二进制文件写出它们会更加明显。
要以这种格式将24位颜色转换为16位,只需屏蔽每个组件所需的高位,转换到位置,并OR
一起。
从16位转换回24位颜色,屏蔽每个分量,移位到位,然后将高位复制到低位。
在您的示例中,似乎某些颜色已经缩放和舍入而不是移位。
我强烈建议使用位移方法,而不是按31/255这样的因子进行缩放,因为位移不仅可能更快,而且应该能提供更好的结果。
答案 4 :(得分:1)
您展示的3部分编号适用于24位颜色。十六进制中的128是0x7f,但在您的颜色定义中,它表示为0x0f。同样,255是0xff,但在您的颜色定义中,它表示为0x1f。这表明您需要采用3部分数字并将它们向下移动3位(每种颜色丢失3位颜色数据)。然后将它们组合成一个16位数字:
uint16 color = ((red>>3)<<11) | ((green>>2)<<5) | (blue>>3);
...从早期修改,因为绿色使用6位,而不是5位。
答案 5 :(得分:1)
您需要知道每个颜色通道有多少位。所以是的,颜色有16位,但RGB组件都是这些位的一部分。在你的情况下,红色是5位,绿色是6,蓝色是5.二进制格式如下:
RRRRRGGG GGGBBBBB
还有其他16位颜色格式,例如红色,绿色和蓝色,每个都是5位,然后将剩余的位用作alpha值。
红色和蓝色通道的值范围将从0
到2^5-1 = 31
,而绿色的范围将是0
到2^6-1 = 63
。因此,要从(0->255),(0->255),(0->255)
形式转换颜色,您需要将值从一个映射到另一个。例如,128
范围内的0->255
红色值将映射到红色通道中的(128/255) * 31 = 15.6
,范围为0-31
。如果我们向下舍入,我们得到15
,它以五位表示为01111
。同样,对于绿色通道(有六位),您将获得011111
。因此,(128,128,128)
颜色将映射到01111011 11101111
,其中0x7BEF
为十六进制。
您也可以将其应用于其他值:0,128,128
变为00000011 11101111
0x03EF
。
答案 6 :(得分:1)
代码中显示的颜色为RGB565。如
所示#define Blue 0x001F /* 0, 0, 255 */
#define Green 0x07E0 /* 0, 255, 0 */
#define Red 0xF800 /* 255, 0, 0 */
如果你只是想为这个#defined
列表添加一些新颜色,那么从每个通道转换16位UINT的最简单方法就是将你的值向下移动以松开低位,然后移位和(或者)它们在16bitRGB值中的位置。
这可能会很好地产生条带伪影,并且可能有更好的转换方法。
即
UINT16 blue = 0xFF;
UINT16 green = 0xFF;
UINT16 red = 0xFF;
blue >>= 11; // top 5 bits
green >>= 10; // top 6 bits
red >>= 11; // top 5 bits
UINT16 RGBvalue = blue | (green <<5) | (red << 11)
你可能需要在转换后屏蔽任何不需要的杂散位,因为我不确定它是如何工作的,但我认为上面的代码应该有效。
答案 7 :(得分:1)
基于放松的答案,特别针对使用Arduino 2.8&#34;的Adafruit GFX库。 TFT触摸屏(v2),您可以将此功能添加到您的Arduino草图并使用它内联来计算rgb中的颜色:
uint16_t getColor(uint8_t red, uint8_t green, uint8_t blue)
{
red >>= 3;
green >>= 2;
blue >>= 3;
return (red << 11) | (green << 5) | blue;
}
现在您可以将其内联使用,使用在x0处创建20x20平方的函数进行说明,y0:
void setup() {
tft.begin();
makeSquare(getColor(20,157,217));
}
unsigned long makeSquare(uint16_t color1) {
tft.fillRect(0, 0, 20, 20, color1);
}
可以找到Adafruit GFX库的文档here