C# 为什么 Bitmap.Save 忽略 Bitmap 的 PixelFormat?

发布于 2024-10-11 23:51:59 字数 1402 浏览 3 评论 0原文

我需要以原始 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 位。

I need to process and save images in their original bpp (1 - for BnW, 8 - for gray, 24 - color).
After processing I always have 24bpp (due to processing with Aforge.Net). I pass original bpp to saving function and I'm using the next code for saving:

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

When I pass:

PixelFormat.Format8bppIndexed

I'm getting an exception: "Graphics object can't create image in indexed pixel format" in the line:

Graphics g = Graphics.FromImage(retval);

I've tried the next code:

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

After this "NewImage" has PixelFormat 8bppIndexed, but when I'm saving NewImage:

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

hello.jpg has 24bpp.

I need to keep bpp and image format of original image.

Why Bitmap.Save ignores PixelFormat of Bitmap?

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

Thanks guys, I've found a solution:
http://freeimage.sourceforge.net/license.html

With help of this free library it is possible to save images (especially JPEG ) to Grayscale 8-bit.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

悲凉≈ 2024-10-18 23:51:59

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

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

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

请参阅维基百科上的支持索引颜色的图像文件格式表

I'm almost positive that the JPEG image format doesn't support indexed images. So even though you created the image specifying PixelFormat.Format8bppIndexed, GDI+ is converting it to a different format when you attempt to save it as a JPEG. In this case, you've already determined that's 24 bpp.

Instead, you need to save the image as a BMP or GIF. For example:

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

See the table of image file formats supporting indexed color here on Wikipedia.

再浓的妆也掩不了殇 2024-10-18 23:51:59

以下是将位图转换为 1bpp/8bpp 位图的代码。 C# 中的 1bpp/8bpp。

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

Graphics.FromImage 文档 有备注:

如果图像有索引像素
格式,此方法会抛出一个
消息例外,“A
无法创建图形对象
具有索引像素的图像
格式。”索引像素格式是
如下表所示。

Format1bppIndexed

Format4bppIndexed

Format8bppIndexed

新部分:

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

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

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

您可以从微软下载 WIC explorer 亲自尝试一下
下载网站。

GDI+ 8 位加载/保存错误

标准 JPEG 仅支持 24 位图像。

Here is the code that will convert a Bitmap to 1bpp/8bpp bitmap. 1bpp/8bpp in C#.

In your changePixelFormat method you can check what fixel format it needs to be converted to, then if it's 1bpp or 8 bpp then use code from link and for all other formats use your code.

Graphics.FromImage documentation has remarks:

If the image has an indexed pixel
format, this method throws an
exception with the message, "A
Graphics object cannot be created from
an image that has an indexed pixel
format." The indexed pixel formats are
shown in the following list.

Format1bppIndexed

Format4bppIndexed

Format8bppIndexed

NEW PART:

This is what i found after short googling:

8bpp greyscale images and 8bpp jpg is not supported with gdiplus version
1.0. There is a new version of gdiplus in Windows 7 that supports greyscale
images and more enhanced codec support.

8bpp indexed jpeg images are supported with
Microsoft's WIC API.

You can try it yourself by downloading the WIC explorer from Microsoft's
download site.

GDI+ 8 bit load/save bug

Standard JPEG only supports 24-bit image.

甜`诱少女 2024-10-18 23:51:59

如果您正在寻找真正的 8 位灰度位图图像,那么我制作了 关于它的详细 StackOverflow 帖子。它可以在任何操作系统(Windows/Mac/Linux)上运行,而不仅仅是 Windows 7。我希望它能有所帮助。

If you're looking for a true 8-bit grayscale bitmap image then I made a detailed StackOverflow post about it. It will work on any operating system (Windows/Mac/Linux), not just Windows 7. I hope it helps.

世态炎凉 2024-10-18 23:51:59

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

Use Graphics class for non indexed image.
UseBitmap.LockBits and Bitmap.UnlockBits when processing indexed images

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文