在C#/ GDI +中从Format8bppIndexed转换为Format24bppRgb

时间:2009-03-23 01:11:10

标签: c# gdi+

好吧,我有一个以8位索引格式从外部应用程序传来的图像。我需要将此图像转换为完全相同大小的24位格式。

我尝试创建一个大小相同且类型为Format24bppRgb的新Bitmap,然后使用Graphics对象在其上绘制8位图像,然后将其保存为Bmp。这种方法不会出错,但是当我打开生成的图像时,BMP标题具有各种时髦的值。高度和宽度都是巨大的,此外,还有压缩标志和其他一些有趣(和大)的值。不幸的是,我的特殊要求是将此文件传递给特定的打印机驱动程序,该驱动程序需要具有特定标头值的24位图像(我正试图通过GDI +实现)

有人知道将索引文件“上转换”为非索引的24位文件的示例吗?如果不是一个例子,我应该从哪个路径开始编写自己的路径?

-Kevin Grossnicklaus kvgros@sseinc.com

4 个答案:

答案 0 :(得分:11)

我使用下面的代码将图像从8bpp“上转换”到24bpp。使用十六进制编辑器检查生成的24bpp文件并与8bpp文件进行比较,显示两个文件中的高度和宽度没有差异。也就是说,8bpp图像是1600x1200,而24bpp图像具有相同的值。

    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);
    }

标题中的其他内容看起来合理,图像在我的系统上显示相同。你看到了什么“时髦的价值观”?

答案 1 :(得分:4)

这是我的转换代码。注意源图像和结果图像之间的分辨率匹配。

    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);
                }
            }
        }
    }

答案 2 :(得分:0)

您创建的输入宽度和高度相同的位图似乎很奇怪,但生成的BMP要大得多。你能发一些代码吗?

答案 3 :(得分:0)

问题可能是源图像和输出图像的垂直和水平分辨率之间的差异。如果你加载一个分辨率为72 DPI的8bpp索引位图,然后创建一个新的24bpp位图(默认分辨率将是96 DPI ...至少它在我的系统上)然后使用Graphics.DrawImage blit到new位图,您的图像将略微放大并裁剪。

话虽如此,我不知道如何正确创建输出Bitmap和/或Graphics对象以便在保存时正确缩放。我怀疑它与使用像英寸而不是像素的常见比例创建图像有关。