Colors RGB 24到16位颜色转换-颜色变暗

Colors RGB 24到16位颜色转换-颜色变暗,colors,rgb,linear-interpolation,Colors,Rgb,Linear Interpolation,我注意到在RGB888 24位到16位RGB565之间转换的例行程序导致每次转换时颜色逐渐变暗。。。该公式使用线性插值,如 typedef struct _RGB24 RGB24; struct _RGB24 { BYTE B; BYTE G; BYTE R; }; RGB24 *s; // source WORD *d; // destination WORD r; WORD g; WORD b; // Code to convert from 24-bit to 16

我注意到在RGB888 24位到16位RGB565之间转换的例行程序导致每次转换时颜色逐渐变暗。。。该公式使用线性插值,如

typedef struct _RGB24 RGB24;
struct _RGB24 {
   BYTE B;
   BYTE G;
   BYTE R;
};

RGB24 *s; // source
WORD *d; // destination
WORD r;
WORD g;
WORD b;

// Code to convert from 24-bit to 16 bit
r = (WORD)((double)(s[x].r * 31) / 255.0);
g = (WORD)((double)(s[x].g * 63) / 255.0);
b = (WORD)((double)(s[x].b * 31) / 255.0);
d[x] = (r << REDSHIFT) | (g << GREENSHIFT) | (b << BLUESHIFT);

// Code to convert from 16-bit to 24-bit
s[x].r = (BYTE)((double)(((d[x] & REDMASK) >> REDSHIFT) * 255) / 31.0);
s[x].g = (BYTE)((double)(((d[x] & GREENMASK) >> GREENSHIFT) * 255) / 63.0);
s[x].b = (BYTE)((double)(((d[x] & BLUEMASK) >> BLUESHIFT) * 255) / 31.0);
typedef结构_rgb24rgb24;
结构RGB24{
字节B;
字节G;
字节R;
};
RGB24*s;//来源
单词*d;//目的地
单词r;
g字;
b字;
//将24位转换为16位的代码
r=(字)((双)(s[x].r*31)/255.0);
g=(字)((双)(s[x].g*63)/255.0);
b=(字)((双)(s[x].b*31)/255.0);
d[x]=(r>绿移)*255)/63.0);
s[x].b=(字节)((双精度)((d[x]&BLUEMASK)>>BLUESHIFT)*255)/31.0);

从16位到24位的转换是相似的,但有反向插值。。。我不明白,如果颜色是相反的,那么每次在方程中循环时,这些值是如何变得越来越低的。。。最初没有双精度转换,但我想如果我将它设为浮点除法,它就不会有衰减。。。但是它仍然…

double
转换为
WORD
不会对
double
值进行四舍五入-它会截断十进制数字。您需要使用某种舍入例程来获得舍入行为。通常,你想要



还要注意,从24位到16位的转换会永久丢失信息。当然,要将24位信息放入16位是不可能的。通过将16位转换回24位无法将其返回。

将双精度值转换为WORD时,值将被截断。例如 (126*31)/255=15.439,截断为15。因为这些值被截断,所以在每次迭代中它们会逐渐降低。您需要引入舍入(在将计算值转换为整数之前,将其加上0.5)

继续此示例,然后取15并转换回:
(15*255)/31=123.387,截断为123,这是因为16位的值与2相乘 2*2*2*2将显示为rrggbb,在相同的32位情况下,将整个位值乘以2

简言之,16位24位32位用于rgb与2的乘法,并以颜色形式显示值。

简单来说,你应该找到位颜色的概念。在Wikipedia上查看它,希望它能帮助您

既然您正在转换为double,至少使用它来避免溢出,即替换

r = (WORD)((double)(s[x].r * 31) / 255.0);

通过这种方式,编译器还应该在costant中折叠31.0/255.0


显然,如果必须对大量像素重复此操作,则最好创建并使用LUT(查找表)。

不要对这样简单的操作使用浮点。我看到的正常方式是在下转换时截断,但在上转换时扩展(所以0b11111变为0b11111)

//从24位转换为16位的代码
r=s[x].r>>(8位红色);
g=s[x].g>>(8个绿色位);
b=s[x].b>>(8-BLUEBITS);
d[x]=(r(2*REDBITS-8);//abcdeabc
s[x].g=(d[x]&GREENMASK)>>GREENSHIFT;//00abcdef
s[x].g=s[x].g>(2*GREENBITS-8);//abcdefab
s[x].b=(d[x]&BLUEMASK)>>BLUESHIFT;//000abcde
s[x].b=s[x].b>(2*BLUEBITS-8);//abcdeabc

我知道,但在转换后,它似乎会在一个值上保持稳定,但转换后的信息会再次变暗…转换后的信息会再次变暗…转换后的信息会再次变暗…等等。换句话说,如果我将16位颜色转换为24位颜色,则根本不修改它,而是将其转换回16位,它是d比这更苍白original@user482910:我意识到了这一点。我编辑了我的文章,提供了更多的信息。这是一个舍入问题,而不是位掩码问题。我忘了提到同样的问题也适用于逆变换。
r = (WORD)round(s[x].r / 255.0 * 31.0); 
// Code to convert from 24-bit to 16 bit
r = s[x].r >> (8-REDBITS);
g = s[x].g >> (8-GREENBITS);
b = s[x].b >> (8-BLUEBITS);
d[x] = (r << REDSHIFT) | (g << GREENSHIFT) | (b << BLUESHIFT);

// Code to convert from 16-bit to 24-bit
s[x].r = (d[x] & REDMASK) >> REDSHIFT;                        // 000abcde
s[x].r = s[x].r << (8-REDBITS) | s[x].r >> (2*REDBITS-8);     // abcdeabc
s[x].g = (d[x] & GREENMASK) >> GREENSHIFT;                    // 00abcdef
s[x].g = s[x].g << (8-GREENBITS) | s[x].g >> (2*GREENBITS-8); // abcdefab
s[x].b = (d[x] & BLUEMASK) >> BLUESHIFT;                      // 000abcde
s[x].b = s[x].b << (8-BLUEBITS) | s[x].b >> (2*BLUEBITS-8);   // abcdeabc