Archived

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

Converting Images to 8Bit

This topic is 6012 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Whats the best way to convert a 16, 24 or 32 bit surface into an 8 bit one, with a given palette? The way i''m doing it right now, is going through each pixel, checking each palette entry and finidn which one is closest, numerically. This however is very slow, taking about a minute on my 800mhz pIII, is there a better way of doing this? I know corel photopaint can convert a bitmap into an 8bit surface in a manner of seconds. The wymsical wyvern

Share this post


Link to post
Share on other sites
There are quite a few algorithms and research already available for colour conversions - a web search will be the best.

IIRC common methods include transforming the RGB data into a different space (such as HSV) and colour cube/octree lookups.

If you have a fixed palette, it will probably be fairly easy to do, imagine a 3D array/cube of bytes, where each axis represents an element of colour (R=X, G=Y, B=Z). If each byte in the cube represented a palette entry the lookup would be super fast - if you were doing loads of these conversions it''d probably be worth precalculating something like that. If not, then there are plenty of optimised lookup methods based on the same sort of idea.

--
Simon O''''Connor
Creative Asylum Ltd
www.creative-asylum.com

Share this post


Link to post
Share on other sites
Yeah, I''d be interested in the solution to this aswell. I''ve been searching for awhile, and the best pseudo code I found was:

quote:

Read pixel.
Extract components.
Find closest match in palette.
Write pixel index.



Which wasn''t too helpful, as it''s the searching I''m having trouble with (speedwise).

I wrote my own image convertor, but the rgb -> palette coversion''s got me stumped. So I cheated and used GDI until I come up a nice solution by myself.

Waassaap!!

Share this post


Link to post
Share on other sites
OH I see what you mean!
ur meaning to say: make an array like this:

unsigned __int8 lookup[256][256][256]

go through the above lookup like i ded with the bitmap:
//// Find best colour
for( e = 0; e < 256; e++ )
{
c = pPalette->colors[e];
usDistance = abs( ( c.r + c.g + c.b ) - ( r + g + b ) );
if( usDistance < usClosestDistance )
{
//// This colour is better
usClosestDistance = usDistance;
usClosestEntry = e;
}
}
.... for each lookup entry, then go through all the bitmaps:

(where r,g,b = the current pixel r,g, and b values respectively)
newsurface[yaddapixel] = lookup[r][g];

Like that?

Share this post


Link to post
Share on other sites
Your palette is just 256 bytes which reference a ''real'' color. Well, that real color is just a number, like red * 65536 + green * 256 + blue.

Just find the value of each color and load it in to another two dimensional array and sort it.

struct SortedPalette
{
int PaletteIndex;
int Value;
};

SortedPalette TheSortedPalette[256];

So first you copy the PaletteIndex values in, from 0 to 255, and their corresponding Value''s of the ''real'' color. Then you sort it. So TheSortedPalette[0].Value would equal 0, for black, and the Index is also 0. TheSortedPalette[255].Value will be 255^3 for white and the Index should be 15 or some such.

Then, when you get your 24 bit (convert 16 bit values to 24 bit) value, you just compare it to the array of sorted palette values, and whichever is closest will tell you which palette entry it is good enough for.

You''re of course looking for the closest value, since 99% of your colors won''t be found in the 8 bit palette.

I hope that''s clear enough...

G-luck,
-Alamar

Share this post


Link to post
Share on other sites
Guest Anonymous Poster

How about a 256k lookup table?


unsigned char lookup[64][64][64];


Think of the table as an 18-bit color space. Where you fill each entry with the closest palette index as if you were working in 18-bit color instead of 24-bit.

Once your lookup table is populated, iterate through your bitmap, converting each pixel''s 24-bit color to an 18-bit color, and looking up the palette index in the table.

Share this post


Link to post
Share on other sites