This should produce much more desireable output. Now, I can't help you with RGB -> HSB conversion, but the find someone who does or even some code that does is trivial.
Finding best color match
int TxtCmapPrivate::find_rgb (int r, int g, int b)
{
if (r>255) r=255; else if (r<0) r=0;
if (g>255) g=255; else if (g<0) g=0;
if (b>255) b=255; else if (b<0) b=0;
int i, min, mindist;
mindist = 1000L*256*256;
min = -1;
register int red, green, blue, dist;
for (i = 1 ; i < 256 ; i++) // Color 0 is not used, it is reserved for transparency
if (alloc)<BR> {<BR> red = r - rgb_values[(i<<2)+0];<BR> green = g - rgb_values[(i<<2)+1];<BR> blue = b - rgb_values[(i<<2)+2];<BR> dist = (299*red*red) + (587*green*green) + (114*blue*blue);<BR> if (dist == 0) return i;<BR> if (dist < mindist) { mindist = dist; min = i; }<BR> }<BR> return min;<BR>}<P>The trick is to make difference between colors so distance calculations will be more accurate.<P>——————<BR>FlyFire/CodeX<BR> <A HREF="http://codexorg.webjump.com" TARGET=_blank>http://codexorg.webjump.com</A> <BR>
http://codexorg.webjump.com
The Crystal Space example looks about the same as Allegro, but does anyone know where the 'magic numbers' come from? CS uses 299, 587, 114, but allegro uses 30*30, 59*59, and 11*11. I guess it makes some sense in that humans discern green more than other colors, so its weighted more, but why are the numbers different? Maybe I'll run across the answer looking at the color space conversion routines.
This is from a book called 'Programmer's Guide to the EGA and VGA Cards'....
gray scale = (0.30 x red) +
(0.59 x green) +
(0.11 x blue)
In creating the gray scale, 30 percent of the red intensity is added to 59 percent of the green intensity and added to 11 percent of the blue intensity. Because the resultant intensity is equal to 100 percent of the intensity of the three colors, the intensity of a gray scale will result in a gray scale of the same value. For example, assume that the three color values are 40, 40, 40 for red, green, blue. This produces a gray scale of intensity 40. The resultant gray scale would be (.30 x 40) + (.59 x 40) + (.11 x 40)
= 1.0 x 40 = 40..............
What i found out from CS example above is that 299 almost = 30% x 1000L, 587 almost = 59% x 1000L, 114 almost = 11% x 1000L.......
that's all i can help here.
__I believe, Rock2000, that you may also want to make the images look good. The next logical step would be to implement a dithering routine.
__Preferably it would be error diffusion; unfortunately I know zilch about it. Perhaps there's a thread in the message board. I couldn't find one, though. Maybe someone could start a new thread on dithering ! [hint, hint]
However, I've looked at the source code for Allegro because it has lookup tables, which I figured I'd use, but it seems to use some sort of weighted squares approach that I don't understand (and there is pretty much no comments). What is the best approach, or where are any good explanations/algorithms on this?
Rock
Do check out:
A Description of Using Error Diffusion for Graphics
and
Sloppy's palette selection concept is pretty amazing, and works quite well (given the sample images) as far as I can implement it.. but dithering is still needed - I wish I knew how photoshop does it because Adobe has made a really nice weighted dithering scheme..