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

我需要处理并保存原始bpp中的图像(1 – 对于BnW,8 – 对于灰色,24 – 颜色)。 处理后我总是有24bpp(由于使用Aforge.Net处理)。 我将原始bpp传递给保存function,我正在使用下一个代码进行保存:

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转换为1bpp / 8bpp位图的代码。 C#中的1bpp / 8bpp。

在你的changePixelFormat方法中,你可以检查它需要转换成什么fixel格式,然后如果它是1bpp或8 bpp然后使用链接代码和所有其他格式使用你的代码。

Graphics.FromImage 文档备注:

如果图像具有索引像素格式,则此方法会抛出exception,并显示消息“无法从具有索引像素格式的图像创建图形对象”。 索引像素格式显示在以下列表中。

Format1bppIndexed

Format4bppIndexed

Format8bppIndexed

新部分:

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

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

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

您可以从Microsoft的下载站点下载WIC资源管理器来自行尝试。

GDI + 8位加载/保存错误

标准JPEG仅支持24位图像。

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

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

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

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

如果您正在寻找一个真正的8位灰度位图图像,那么我就此发了一篇详细的StackOverflowpost 。 它适用于任何操作系统(Windows / Mac / Linux),而不仅仅是Windows 7.我希望它有所帮助。

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