【问题标题】:C# Why Bitmap.Save ignores PixelFormat of Bitmap?C# 为什么 Bitmap.Save 忽略 Bitmap 的 PixelFormat?
【发布时间】:2011-06-08 11:12:06
【问题描述】:

我需要以原始 bpp 处理和保存图像(1 - 用于 BnW,8 - 用于灰色,24 - 彩色)。 处理后我总是有 24bpp(由于使用 Aforge.Net 处理)。我将原始 bpp 传递给保存函数,我正在使用下一个代码进行保存:

private static Bitmap changePixelFormat(Bitmap input, PixelFormat format)
    {
        Bitmap retval = new Bitmap(input.Width, input.Height, format);
        retval.SetResolution(input.HorizontalResolution, input.VerticalResolution);
        Graphics g = Graphics.FromImage(retval);
        g.DrawImage(input, 0, 0);
        g.Dispose();
        return retval;
    }

当我通过时:

PixelFormat.Format8bppIndexed

我遇到了一个异常:“图形对象无法以索引像素格式创建图像”:

Graphics g = Graphics.FromImage(retval);

我已经尝试了下一个代码:

Bitmap s = new Bitmap("gray.jpg");
        Bitmap NewPicture = s.Clone(new Rectangle(0, 0, s.Width, s.Height),                   PixelFormat.Format8bppIndexed);

在此“NewImage”具有 PixelFormat 8bppIndexed 之后,但是当我保存 NewImage 时:

NewPicture.Save("hello.jpg", ImageFormat.Jpeg);

hello.jpg 有 24bpp。

我需要保留原始图像的bpp和图像格式。

为什么Bitmap.Save会忽略Bitmap的PixelFormat?

================================================ ========

谢谢各位,我找到了解决办法: http://freeimage.sourceforge.net/license.html

借助这个免费库,可以将图像(尤其是 JPEG)保存为灰度 8 位。

【问题讨论】:

  • 那么,问题是什么?为什么Bitmap.Save会忽略正在保存的图片的PixelFormat?或者我如何使用索引像素格式解决Graphics.FromImage 引发的异常?
  • 抱歉,我没有添加问题。问题是:“为什么 Bitmap.Save 会忽略 Bitmap 的 PixelFormat?”
  • 如果您想要 8 位索引,则必须将其保存为 GIF。
  • GDI+ 无法做到这一点,它对索引像素格式的支持非常弱。并没有什么意义,这在 Windows 3 天很重要。当操作系统与您今天使用的桌面壁纸图像一样大时。
  • @HansPassant 如果您使用非常大的位图(例如:naturalearthdata.com/downloads/10m-raster-data/10m-gray-earth),仍然可以使用它

标签: c# image-processing bitmap pixelformat


【解决方案1】:

我几乎可以肯定 JPEG 图像格式不支持索引图像。因此,即使您创建了指定 PixelFormat.Format8bppIndexed 的图像,当您尝试将其保存为 JPEG 时,GDI+ 也会将其转换为不同的格式。在本例中,您已经确定为 24 bpp。

相反,您需要将图像保存为 BMP 或 GIF。例如:

NewPicture.Save("hello.jpg", ImageFormat.Bmp);

查看支持索引颜色的图像文件格式表here on Wikipedia

【讨论】:

    【解决方案2】:

    这是将位图转换为 1bpp/8bpp 位图的代码。 1bpp/8bpp in C#.

    在您的 changePixelFormat 方法中,您可以检查需要将其转换为哪种固定格式,如果是 1bpp 或 8 bpp,则使用链接中的代码,对于所有其他格式,请使用您的代码。

    Graphics.FromImagedocumentation有备注:

    如果图像具有索引像素 格式,这个方法抛出一个 消息异常,“A 不能从创建图形对象 具有索引像素的图像 格式。”索引的像素格式是 如下表所示。

    Format1bppIndexed

    Format4bppIndexed

    Format8bppIndexed

    新部分:

    这是我在谷歌搜索后发现的:

    gdiplus 版本不支持 8bpp 灰度图像和 8bpp jpg 1.0。 Windows 7 中有一个新版本的 gdiplus 支持灰度 图像和更增强的编解码器支持。

    支持 8bpp 索引 jpeg 图像 微软的 WIC API。

    您可以通过从 Microsoft 下载 WIC 资源管理器自己尝试 下载网站。

    GDI+ 8 bit load/save bug

    标准 JPEG 仅支持 24 位图像。

    【讨论】:

    【解决方案3】:

    如果您正在寻找一个真正的 8 位灰度位图图像,那么我为它制作了一个 detailed StackOverflow post。它适用于任何操作系统(Windows/Mac/Linux),而不仅仅是 Windows 7。我希望它有所帮助。

    【讨论】:

      【解决方案4】:

      对非索引图像使用 Graphics 类。 处理索引图像时使用Bitmap.LockBits 和Bitmap.UnlockBits

      【讨论】:

        猜你喜欢
        • 2015-02-23
        • 1970-01-01
        • 2013-08-09
        • 1970-01-01
        • 1970-01-01
        • 2021-11-06
        • 2019-03-22
        • 2017-07-07
        • 2012-01-30
        相关资源
        最近更新 更多