C# - Copy an Image into an 8-bit Indexed Image
I want to create an 8-bit indexed image from a regular 32-bit Image object.
Bitmap img = new Bitmap(imgPath); // 32-bit
Bitmap img8bit = new Bitmap(imgW, imgH, Form开发者_开发百科at8bppIndexed); // 8-bit
// copy img to img8bit -- HOW?
img8bit.Save(imgNewPath, ImageFormat.Png);
I cannot use SetPixel to copy it over pixel-by-pixel since Graphics doesn't work with indexed images.
How else?
I found a C# library that converts a bitmap into a palettized (8-bit) image. The technique is fast because it calls GDI32 (the windows graphics system) directly.
To convert to an 8bpp (palettized) image with a greyscale palette, do
System.Drawing.Bitmap b0 = CopyToBpp(b,8);
If you want to convert to an image with a different palette, look at the comments in the source code of CopyToBpp for suggestions. Note that, when you convert to a 1bpp or 8bpp palettized copy, Windows will look at each pixel one by one, and will chose the palette entry that's closest to that pixel. Depending on your source image and choice of palette, you may very well end up with a resulting image that uses only half of the colours available in the palette.
Converting an arbitrary RGBA image to an 8-bit indexed bitmap is a non-trivial operation; you have to do some math to determine the top 256 colors and round the rest (or do dithering, etc).
http://support.microsoft.com/kb/319061 has the details of everything except for a good algorithm, and it should give you an idea of how to get started.
精彩评论