C++ 如何将16位十六进制颜色转换为C++;

C++ 如何将16位十六进制颜色转换为C++;,c++,colors,C++,Colors,我有uint16\u t颜色,需要将其转换为RGB等效颜色。十六进制设置为前5位表示红色,下6位表示绿色,最后5位表示蓝色 到目前为止,我已经找到了一些接近解决方案的东西,但不完全是因为截断 void hexToRGB(uint16_t hexValue) { int r = ((hexValue >> 11) & 0x1F); // Extract the 5 R bits int g = ((hexValue >> 5) & 0x3

我有
uint16\u t颜色
,需要将其转换为RGB等效颜色。十六进制设置为前5位表示红色,下6位表示绿色,最后5位表示蓝色

到目前为止,我已经找到了一些接近解决方案的东西,但不完全是因为截断

void hexToRGB(uint16_t hexValue)
{

    int r = ((hexValue >> 11) & 0x1F);  // Extract the 5 R bits
    int g = ((hexValue >> 5) & 0x3F);   // Extract the 6 G bits
    int b = ((hexValue) & 0x1F);        // Extract the 5 B bits

    r = ((r * 255) / 31) - 4;
    g = ((g * 255) / 63) - 2;
    b = ((b * 255) / 31) - 4;

    printf("r: %d, g: %d, b: %d\n",r, g, b);
}

int main()
{
    //50712=0xC618 
    hexToRGB(50712);    
    return 0;
}

上面的例子产生了
r:193,g:192,b:193
,应该是
r:192,g:192,b:192
,我一直在使用这个问题作为参考,但我基本上需要一个反向的解决方案来回答他们的问题。

下面是什么:

unsigned r = (hexValue & 0xF800) >> 8;       // rrrrr... ........ -> rrrrr000
unsigned g = (hexValue & 0x07E0) >> 3;       // .....ggg ggg..... -> gggggg00
unsigned b = (hexValue & 0x1F) << 3;         // ............bbbbb -> bbbbb000

printf("r: %d, g: %d, b: %d\n", r, g, b);
然后0xC618-->197194197,而不是预期的192192192,但0xFFFF为纯白色,0x0000为纯黑色。

没有从RGB565刻度转换为RGB888的“正确”方法。每个颜色分量都需要从其5位或6位范围缩放到8位范围,并且有不同的方法来实现这一点,每个方法通常会在图像中产生不同类型的视觉伪影

当在n位范围内缩放颜色时,我们可能会决定希望以下内容通常为真:

  • 绝对黑色(例如5位空间中的
    00000
    )必须映射到8位空间中的绝对黑色
  • 绝对白色(例如5位空间中的11111)必须映射到8位空间中的绝对白色
实现这一点意味着我们基本上希望将值从n位空间中的(2n-1)阴影缩放到8位空间中的(28-1)阴影。也就是说,我们希望以某种方式有效地做到以下几点:

r_8 = (255 * r / 31)
g_8 = (255 * g / 63)
b_8 = (255 * b / 31)
通常采取的不同方法有:

  • 整数除法缩放
  • 使用浮动除法和四舍五入进行缩放
  • 将位移到8位空间并添加最高有效位
后一种方法实际上如下所示

r_8 = (r << 3) | (r >> 2)
g_8 = (g << 2) | (g >> 4)
b_8 = (b << 3) | (b >> 2)
r_8=(r>2)
g_8=(g>4)
b_8=(b>2)
对于您的5位值
11000
,这将导致8位值:

  • 197
  • 197
  • 198(
    11000000 | 110
同样,您的六位值
110000
将产生以下8位值:

  • 194
  • 194
  • 195(
    11000000 | 11

((r*255)/31)
这样的表达式不会给出精确的结果,除非您使用浮点运算。显然,5位中可表示的值少于8位中的值,因此并非所有值都可以完美地往返。此外,您的转换公式很奇怪-0将转换为负值。最简单的方法是将
r
b
乘以8,将
g
乘以4——尽管这不会产生最纯净的白色(得到的白色最多是
(248252248)
)。祝你好运。565是可怕的,不应该被创造出来。你永远无法使G分量匹配R和B。请看两个除数31和63,以及一个除数是另一个除数的两倍多一点。如果可能的话,我强烈建议使用ARGB 1555或RGB 555。在RGB 565中甚至不能表示灰度。转换公式一定有问题。如果你有一个0,0,0的输入,输出将是-4,-2,-4。谢谢你发布这个@Rudy Velthius!
r_8 = (r << 3) | (r >> 2)
g_8 = (g << 2) | (g >> 4)
b_8 = (b << 3) | (b >> 2)