Reputation: 694
I have some part of code done, but in some comparisons, nearest values are incorrectly. Example:
Correct:
Rgb value | Value from array
0xFFFFFD = 0xFFFFFF
Incorrect: Fixed code
Rgb value | Value from array
0xF4F939 = 0xFF0000 (should be 0xFFFF00)
Console Output: (Correct)
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>
Console Output: (Incorrect)
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>
Those RGB color code are listed in an array:
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
};
Then to get the nearest number I do:
nearest = findKey(data, pcolor);
And this is the complete code:
#include <stdio.h>
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 < 256; a++) {
if (diff > abs( key - Array1[a] )) {
diff = abs( key - Array1[a]);
Num1 = Array1[a];
}
}
return Num1;
}
There are some unused variables and old code.
Any ideas?
Upvotes: 4
Views: 4010
Reputation: 9416
I would think that using the 3-D distance formula would be a more accurate way to compute the 'nearest' color (since you only care about comparing, you can skip the sqrt()
at the end).
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
actually you can skip the abs()
calls too, but putting them in makes it clearer, perhaps?
Upvotes: 3
Reputation: 15847
To find the "optical" closest color you have to estimate the difference between the color components of the two color you're comparing.
In order to do that you have to split the 24 bit value into 8 bit color components r, g, b.
Then you compare the components.
A naive method to do that is just sum the absolute value of the difference of the respective components.
More accurate formulas can be found googling, I guess.
// 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 );
Upvotes: 4