使用C中的调色板数组查找最近的RGB值

我已完成部分代码,但在某些比较中,最接近的值不正确。 例:

正确:

Rgb value | Value from array 0xFFFFFD = 0xFFFFFF 

不正确: 固定代码

 Rgb value | Value from array 0xF4F939 = 0xFF0000 (should be 0xFFFF00) 

控制台输出:(正确)

 C:\Users\honguito\Desktop\Bat\Game_Batch_Files\24_to_8_bitmap>24_to_8_bit_palett e The closest color of 0xFFFFFD is: '0xFFFFFF' C:\Users\honguito\Desktop\Bat\Game_Batch_Files\24_to_8_bitmap> 

控制台输出:(不正确)

 C:\Users\honguito\Desktop\Bat\Game_Batch_Files\24_to_8_bitmap>24_to_8_bit_palett e The closest color of 0xF4F939 is: '0xFF0000' C:\Users\honguito\Desktop\Bat\Game_Batch_Files\24_to_8_bitmap> 

那些RGB颜色代码列在一个数组中:

 int data[] = { 0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080, 0x008080, 0xC0C0C0, 0xC0DCC0, 0xA6CAF0, 0x402000, 0x602000, 0x802000, 0xA02000, 0xC02000, 0xE02000, 0x004000, 0x204000, 0x404000, 0x604000, 0x804000, 0xA04000, 0xC04000, 0xE04000, 0x006000, 0x206000, 0x406000, 0x606000, 0x806000, 0xA06000, 0xC06000, 0xE06000, 0x008000, 0x208000, 0x408000, 0x608000, 0x808000, 0xA08000, 0xC08000, 0xE08000, 0x00A000, 0x20A000, 0x40A000, 0x60A000, 0x80A000, 0xA0A000, 0xC0A000, 0xE0A000, 0x00C000, 0x20C000, 0x40C000, 0x60C000, 0x80C000, 0xA0C000, 0xC0C000, 0xE0C000, 0x00E000, 0x20E000, 0x40E000, 0x60E000, 0x80E000, 0xA0E000, 0xC0E000, 0xE0E000, 0x000040, 0x200040, 0x400040, 0x600040, 0x800040, 0xA00040, 0xC00040, 0xE00040, 0x002040, 0x202040, 0x402040, 0x602040, 0x802040, 0xA02040, 0xC02040, 0xE02040, 0x004040, 0x204040, 0x404040, 0x604040, 0x804040, 0xA04040, 0xC04040, 0xE04040, 0x006040, 0x206040, 0x406040, 0x606040, 0x806040, 0xA06040, 0xC06040, 0xE06040, 0x008040, 0x208040, 0x408040, 0x608040, 0x808040, 0xA08040, 0xC08040, 0xE08040, 0x00A040, 0x20A040, 0x40A040, 0x60A040, 0x80A040, 0xA0A040, 0xC0A040, 0xE0A040, 0x00C040, 0x20C040, 0x40C040, 0x60C040, 0x80C040, 0xA0C040, 0xC0C040, 0xE0C040, 0x00E040, 0x20E040, 0x40E040, 0x60E040, 0x80E040, 0xA0E040, 0xC0E040, 0xE0E040, 0x000080, 0x200080, 0x400080, 0x600080, 0x800080, 0xA00080, 0xC00080, 0xE00080, 0x002080, 0x202080, 0x402080, 0x602080, 0x802080, 0xA02080, 0xC02080, 0xE02080, 0x004080, 0x204080, 0x404080, 0x604080, 0x804080, 0xA04080, 0xC04080, 0xE04080, 0x006080, 0x206080, 0x406080, 0x606080, 0x806080, 0xA06080, 0xC06080, 0xE06080, 0x008080, 0x208080, 0x408080, 0x608080, 0x808080, 0xA08080, 0xC08080, 0xE08080, 0x00A080, 0x20A080, 0x40A080, 0x60A080, 0x80A080, 0xA0A080, 0xC0A080, 0xE0A080, 0x00C080, 0x20C080, 0x40C080, 0x60C080, 0x80C080, 0xA0C080, 0xC0C080, 0xE0C080, 0x00E080, 0x20E080, 0x40E080, 0x60E080, 0x80E080, 0xA0E080, 0xC0E080, 0xE0E080, 0x0000C0, 0x2000C0, 0x4000C0, 0x6000C0, 0x8000C0, 0xA000C0, 0xC000C0, 0xE000C0, 0x0020C0, 0x2020C0, 0x4020C0, 0x6020C0, 0x8020C0, 0xA020C0, 0xC020C0, 0xE020C0, 0x0040C0, 0x2040C0, 0x4040C0, 0x6040C0, 0x8040C0, 0xA040C0, 0xC040C0, 0xE040C0, 0x0060C0, 0x2060C0, 0x4060C0, 0x6060C0, 0x8060C0, 0xA060C0, 0xC060C0, 0xE060C0, 0x0080C0, 0x2080C0, 0x4080C0, 0x6080C0, 0x8080C0, 0xA080C0, 0xC080C0, 0xE080C0, 0x00A0C0, 0x20A0C0, 0x40A0C0, 0x60A0C0, 0x80A0C0, 0xA0A0C0, 0xC0A0C0, 0xE0A0C0, 0x00C0C0, 0x20C0C0, 0x40C0C0, 0x60C0C0, 0x80C0C0, 0xA0C0C0, 0xFFFBF0, 0xA0A0A4, 0x808080, 0xFF0000, 0x00FF00, 0xFFFF00, 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF }; 

然后得到我最近的数字:

 nearest = findKey(data, pcolor); 

这是完整的代码:

 #include  int main () { //int pcolor = 0xF4F939; int pcolor = 0xFFFFFD; //int pcolor = 0x700000; //int pcolor = 0x21A0C0; int cmp[256]; int cmp2[256]; int data[] = { 0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080, 0x008080, 0xC0C0C0, 0xC0DCC0, 0xA6CAF0, 0x402000, 0x602000, 0x802000, 0xA02000, 0xC02000, 0xE02000, 0x004000, 0x204000, 0x404000, 0x604000, 0x804000, 0xA04000, 0xC04000, 0xE04000, 0x006000, 0x206000, 0x406000, 0x606000, 0x806000, 0xA06000, 0xC06000, 0xE06000, 0x008000, 0x208000, 0x408000, 0x608000, 0x808000, 0xA08000, 0xC08000, 0xE08000, 0x00A000, 0x20A000, 0x40A000, 0x60A000, 0x80A000, 0xA0A000, 0xC0A000, 0xE0A000, 0x00C000, 0x20C000, 0x40C000, 0x60C000, 0x80C000, 0xA0C000, 0xC0C000, 0xE0C000, 0x00E000, 0x20E000, 0x40E000, 0x60E000, 0x80E000, 0xA0E000, 0xC0E000, 0xE0E000, 0x000040, 0x200040, 0x400040, 0x600040, 0x800040, 0xA00040, 0xC00040, 0xE00040, 0x002040, 0x202040, 0x402040, 0x602040, 0x802040, 0xA02040, 0xC02040, 0xE02040, 0x004040, 0x204040, 0x404040, 0x604040, 0x804040, 0xA04040, 0xC04040, 0xE04040, 0x006040, 0x206040, 0x406040, 0x606040, 0x806040, 0xA06040, 0xC06040, 0xE06040, 0x008040, 0x208040, 0x408040, 0x608040, 0x808040, 0xA08040, 0xC08040, 0xE08040, 0x00A040, 0x20A040, 0x40A040, 0x60A040, 0x80A040, 0xA0A040, 0xC0A040, 0xE0A040, 0x00C040, 0x20C040, 0x40C040, 0x60C040, 0x80C040, 0xA0C040, 0xC0C040, 0xE0C040, 0x00E040, 0x20E040, 0x40E040, 0x60E040, 0x80E040, 0xA0E040, 0xC0E040, 0xE0E040, 0x000080, 0x200080, 0x400080, 0x600080, 0x800080, 0xA00080, 0xC00080, 0xE00080, 0x002080, 0x202080, 0x402080, 0x602080, 0x802080, 0xA02080, 0xC02080, 0xE02080, 0x004080, 0x204080, 0x404080, 0x604080, 0x804080, 0xA04080, 0xC04080, 0xE04080, 0x006080, 0x206080, 0x406080, 0x606080, 0x806080, 0xA06080, 0xC06080, 0xE06080, 0x008080, 0x208080, 0x408080, 0x608080, 0x808080, 0xA08080, 0xC08080, 0xE08080, 0x00A080, 0x20A080, 0x40A080, 0x60A080, 0x80A080, 0xA0A080, 0xC0A080, 0xE0A080, 0x00C080, 0x20C080, 0x40C080, 0x60C080, 0x80C080, 0xA0C080, 0xC0C080, 0xE0C080, 0x00E080, 0x20E080, 0x40E080, 0x60E080, 0x80E080, 0xA0E080, 0xC0E080, 0xE0E080, 0x0000C0, 0x2000C0, 0x4000C0, 0x6000C0, 0x8000C0, 0xA000C0, 0xC000C0, 0xE000C0, 0x0020C0, 0x2020C0, 0x4020C0, 0x6020C0, 0x8020C0, 0xA020C0, 0xC020C0, 0xE020C0, 0x0040C0, 0x2040C0, 0x4040C0, 0x6040C0, 0x8040C0, 0xA040C0, 0xC040C0, 0xE040C0, 0x0060C0, 0x2060C0, 0x4060C0, 0x6060C0, 0x8060C0, 0xA060C0, 0xC060C0, 0xE060C0, 0x0080C0, 0x2080C0, 0x4080C0, 0x6080C0, 0x8080C0, 0xA080C0, 0xC080C0, 0xE080C0, 0x00A0C0, 0x20A0C0, 0x40A0C0, 0x60A0C0, 0x80A0C0, 0xA0A0C0, 0xC0A0C0, 0xE0A0C0, 0x00C0C0, 0x20C0C0, 0x40C0C0, 0x60C0C0, 0x80C0C0, 0xA0C0C0, 0xFFFBF0, 0xA0A0A4, 0x808080, 0xFF0000, 0x00FF00, 0xFFFF00, 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF }; int nearIndex,nearest, result; nearest = findKey(data, pcolor); printf("The closest color of 0x%X is: '0x%X'\n", pcolor, nearest); //system("pause"); } int findKey(int Array1[], int key){ int diff = abs( key - Array1[0]); int Num1 = 0; int Num2 = 0; for (int a = 0; a  abs( key - Array1[a] )) { diff = abs( key - Array1[a]); Num1 = Array1[a]; } } return Num1; } 

有一些未使用的变量和旧代码。

有任何想法吗?

要找到“光学”最接近的颜色,您必须估计您要比较的两种颜色的颜色分量之间的差异。

为此,您必须将24位值拆分为8位颜色分量r,g,b。

然后比较组件。

一种简单的方法就是将各个组件的差异的绝对值相加。

我想,可以找到更准确的公式谷歌搜索。

 // two colors to compare int c1; int c2; // split c1 and c2 into their respective color components r1 = c1 / 0x010000; g1 = (c1 % 0x010000) / 0x00100; b1 = c1 % 0x000100; r2 = c2 / 0x010000; g2 = (c2 % 0x010000) / 0x00100; b2 = c2 % 0x000100; // color "distance" diff = abs( r1 - r2 ) + abs( g1 - g2 ) + abs ( b1 - b2 ); 

我认为使用三维距离公式可以更准确地计算“最近”的颜色(因为你只关心比较,你可以跳过最后的sqrt() )。

 dist_r = abs(r1 - r2); dist_g = abs(g1 - g2); dist_b = abs(b1 - b2); dist_3d_sqd = (dist_r * dist_r) + (dist_g * dist_g) + (dist_b * dist_b 

实际上你也可以跳过abs()调用,但是把它们放进去可能会更清楚吗?