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