6
votes

Alright, I have an image coming through from an external application in an 8-bit indexed format. I need this image converted to a 24-bit format of the exact same size.

I've tried creating a new Bitmap of the same size and of type Format24bppRgb and then using a Graphics object to draw the 8-bit image over it before saving it as a Bmp. This approach doesn't error out but when I open the resulting image the BMP header has all kinds of funky values. The height and width are HUGE and, in addition, there are funny (and large) values for the compression flags and a few others. Unfortunately my particular requirements are to pass this file off to a specific printer driver that demands a 24-bit image with specific header values (which I'm trying to achieve through GDI+)

Anyone know of an example on "up-converting" an indexed file to a not-indexed 24-bit file? If not an example, which path should I start down to write my own?

-Kevin Grossnicklaus [email protected]

4

4 Answers

11
votes

I used the code below to "up-convert" an image from 8bpp to 24bpp. Inspecting the generated 24bpp file with a hex editor and comparing against the 8bpp file shows no difference in height and width in the two files. That is, the 8bpp image was 1600x1200, and the 24bpp image has the same values.

    private static void ConvertTo24(string inputFileName, string outputFileName)
    {
        Bitmap bmpIn = (Bitmap)Bitmap.FromFile(inputFileName);

        Bitmap converted = new Bitmap(bmpIn.Width, bmpIn.Height, PixelFormat.Format24bppRgb);
        using (Graphics g = Graphics.FromImage(converted))
        {
            // Prevent DPI conversion
            g.PageUnit = GraphicsUnit.Pixel
            // Draw the image
            g.DrawImageUnscaled(bmpIn, 0, 0);
        }
        converted.Save(outputFileName, ImageFormat.Bmp);
    }

Everything else in the headers looks reasonable, and the images display identical on my system. What "funky values" are you seeing?

4
votes

This is my conversion code. Notice the matching of resolution between source image and resulting image.

    private void ConvertTo24bppPNG(Stream imageDataAsStream, out byte[] data)
    {
        using ( Image img = Image.FromStream(imageDataAsStream) )
        {
            using ( Bitmap bmp = new Bitmap(img.Width, img.Height, PixelFormat.Format24bppRgb) )
            {
                // ensure resulting image has same resolution as source image
                // otherwise resulting image will appear scaled
                bmp.SetResolution(img.HorizontalResolution, img.VerticalResolution);

                using ( Graphics gfx = Graphics.FromImage(bmp) )
                {
                    gfx.DrawImage(img, 0, 0);
                }

                using ( MemoryStream ms = new MemoryStream() )
                {
                    bmp.Save(ms, ImageFormat.Png);
                    data = new byte[ms.Length];
                    ms.Position = 0;
                    ms.Read(data, 0, (int) ms.Length);
                }
            }
        }
    }
0
votes

It seems odd that you're creating a Bitmap of the same width and height as your input, yet the generated BMP is much larger. Can you post some code?

0
votes

The problem is probably the difference between the Vertical- and HorizontalResolution of your source image and your output image. If you load a 8bpp indexed bitmap with a resolution of 72 DPI, and then create a new 24bpp bitmap (default resolution will be 96 DPI... at least it is on my system) and then use Graphics.DrawImage to blit to the new bitmap, your image will appear slightly zoomed in and cropped.

Having said that, I don't know off the top of my head how to properly create the output Bitmap and/or Graphics object to scale properly when saved. I suspect it will have something to do with creating the images using a common scale like inches instead of pixels.