Archived

This topic is now archived and is closed to further replies.

Dark Star

Does anyone know how to get a colour value

Recommended Posts

Guest Anonymous Poster
Hey

It would be nice to have a function like this:
char get_color_index(char r, char g, char b);

but the thing is in MCGA mode you are dealing with
256 specific colors, and with a palette of 64^3
different color combinations.

RGB(18 bit) 6bits per/r, g, and b.
Which each have the range 0-63.
0-63 that is 64 different numbers.

Therefor the maximum number of combinations is
64*64*64 (64^3) = 262 144 combinations.

So if you want the EXACT color index returned from
the function.. sorry that wont work because there
is only 256(0-255) specific indexes.
BUT there are some algorithms to let you get
an index which is the best in the palette back.
Actually it might not be good at all. I mean lets say
you have made a greyscale out of the entire palette.
And you use this function get_color_index();

With lets say: index = get_color_index(0, 0, 63);
You want to have the index for bright blue, BUT
there is no bright blue because we have made a
big greyscale. Anway I don''t know if this helped at all.
Bye



Share this post


Link to post
Share on other sites
depends on, what pallete you have.
You may use 3:3:2 pallete scheme (as 5:6:5 in HiColor) and
then the index calculation is pretty straight forward.
But as you already did guess, 3:3:2 format will cover just very small amount of colours, and it will be hard to use for some nice graphics... (but it is FAST)
Anything more sophisticated will be a LOT slower. You may use custom pallete and search trough it doing the equation:
square(Palete.red - searched.red) + squares of other "deltas (green, blue)" and search for the index with the smallest result of equation (i.e. the "closest color to the searched one") ...
This will maybe lead to the best non-dithered result. (but I didn''t study too much theory about this, so maybe there''s something even better out there).
If you are converting graphics, and the quality (and not speed) is an issue, you may do some dithering while converting... (error dithering is the one I like mostly - you took those "deltas" (i.e. the color value, which has been lost by conversion), and you add them to the next color you are converting, so the "lost" values will accumulate ... I hope you got it ... )


---------------------------------------------------
Ped - Peter Helcmanovsky - 7 Gods demo group
http://7gods.rulez.sk
First Sight Entertainment - http://members.xoom.com/fseteam
---------------------------------------------------

Share this post


Link to post
Share on other sites
What you need is a function that will take an R,G,B value and return the closest match in the palette, right?

Well it''s not a very fast thing to do, so I would recommend making a lookup table if you need it realtime.. but here is the general idea.

(Sorry for the lack of indentation.. the message board takes them out

byte NearestColor(byte *pal, int r, int g, int b)
{
int dist,mind=30000,minc,c;

for(c=0;c<256;c++)
{
dist=abs(pal[c*3]-r)+abs(pal[c*3+1]-g)+abs(pal[c*3+2]-b);
if (dist }
return (byte)minc;
}

This assumes that pal is a 768 byte pointer of r,g,b color values.. (a standard palette that you might send to the video card).

If you use some other palette format.. here is some more pseudoish code

byte NearestColor(byte *pal, int r, int g, int b)
{
int dist,mind=30000,minc,c;

for(c=0;c<256;c++)
{
dist=abs(pal[c].Red - r) + abs(pal[c].Green - g) + abs(pal[c].Blue - b);
if (dist }
return (byte)minc;
}

Hope this helps.. good luck!

Share this post


Link to post
Share on other sites
Wow.. somehow that post really got messed up.
This message board should preserve literals for us programmers!
(It thought my less than sign was an html tag or some crap)

Anyway.. here''s the same concept from scratch
Remember, it''s pseudoish code

Index NearestColor(Palette *Pal, byte r, byte g, byte b)
{
int Dist, MinDist = 30000, MinColor;
int i;

for(i=0;i<256;i++) // for each color
{
Dist = abs(Pal.Red - r) + abs(Pal[i].Green - g) + abs(Pal[i].Blue - b);
if (Dist is less than MinDist) MinDist = Dist, MinColor = i;
}

return MinColor;
}

Share this post


Link to post
Share on other sites