We help IT Professionals succeed at work.

Converting 24bit hbitmap to 8bit?

Olympus asked
Medium Priority
Last Modified: 2008-02-01
How would I properly convert a 24bit bitmap (captured from the screen with BitBlt) to 8bit or 16bit? (or 1bit and 4bit too) And I don't mean just set the destination bitmap to 8 bit and have BitBlt convert it for me; that screws up the colors and freezes up the cpu for about .834 seconds.  I know it has to somehow be done with CreateHalftonePalette() for 8 bit. Any suggestions?
Watch Question

The best way to do it is to select out the colours from the original image that are the most imortant and build a colour table.  There's a good article over at Gamasutra about this.


It's not a specific implementation, but it's a very good guide to the process.


Any more specific code? How about 32bit to 24bit conversion? Whats the most efficient way to do this? Go through each pixel separately and drop the 4th byte?

I don't have specific code for this that's good for general use.  I've only referenced this article as an example for vector quantisation theory.

The simple reason for never having to code this is that almost all modern computer hardware, except for possibly embedded systems or television/video, handle 32-bit RGBA better than any other byte arrangement.

As for 32 to 24, you can drop the fourth byte only if it is an RGBA image.  In that case you're only eliminating the transparencies.  If it's not RGBA, like YUV, then that byte is significant and doesn't drop.It's also since occured to me that some of the better image processing packages, like Photoshop or GIMP, might have a decent colour table builder built in.  It would be worth the time to explore what they have to offer.

In any case, this is the sort of operation that you don't want to do on hte fly. So whatever strategy you use, do it all in preprocessing and not worry about efficiency.

Use the GIMP if you do it by hand.
or GTK the API that the GIMP used to do it in C.



What about CreateHalftonePalette()? I remember seeing an implementation using that function...

I'm not familiar with that function.  What API is it from?



Catch, I rarely program on Windows, so outside of a suggestion to look at what documentation is available on MSDN, I have no idea where to get sample code that would be useful to you.
Reducing a 24b image to a 8b one is a well know problem called "color quantization". There is a common reference sample with C++ source code for this problem. This sample is very simple, very well down and work with BMP files, but you can easily modify it for your needs.

Here is is :


If you ave any problem, I can send it by email.

Given a bitmap, the function GetDIBits will give you a DIB in whatever format you specify in the BITMAPINFO parameter.  You can change bits per pixel this way, you can even make it 8bpp when you specify a palette in your bitmapinfo.  I can't help you pick the colors of the palette, but others already have.
For all of the non-palette conversions, GetDIBits will be able to do the right thing.