我注意到,我在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);从16位到24位的转换是类似的,但使用了反向插值...我不明白,如果颜色是相反的,那么每次循环使用一种颜色时,这些值是如何变得越来越低的。最初没有强制转换为双精度,但我认为如果我将其设为浮点除法,它就不会有衰减……但它还是会...
发布于 2010-11-09 14:24:38
当您将双精度值转换为WORD时,值将被截断。例如,(126x31)/ 255 = 15.439,它被截断为15。因为值被截断,所以它们在每次迭代中逐渐变小。您需要引入四舍五入(在将计算值转换为整数之前将其添加0.5 )
继续这个例子,然后取15并转换回:(15 * 255)/31 = 123.387,它被截断为123
发布于 2011-03-23 19:40:29
对于这样简单的事情,不要使用浮点数。我看到的正常方法是在下转换上截断,但在上转换上扩展(因此0b11111到0b11111111)。
// 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发布于 2010-11-09 14:20:04
将double转换为WORD不会对double值进行舍入-它会截断小数位。您需要使用某种舍入例程来获取舍入行为。通常情况下,您希望round half to even。There is a Stack Overflow question on how to round in C++ if you need it。
还要注意,从24位到16位的转换永久地丢失了信息。当然,将24位的信息放入16位是不可能的。你不能通过从16位转换回24位来恢复它。
https://stackoverflow.com/questions/4130985
复制相似问题