c#当将TIFF转换为PNG时,我如何获得与使用MS Paint相同的压缩
Posted
技术标签:
【中文标题】c#当将TIFF转换为PNG时,我如何获得与使用MS Paint相同的压缩【英文标题】:c# When converting TIFF to PNG how do I get the same compress I get by using MS Paint 【发布时间】:2017-05-01 07:05:34 【问题描述】:这是我用来将 TIFF 转换为 PNG 的代码。
var image = Image.FromFile(@"Test.tiff");
var encoders = ImageCodecInfo.GetImageEncoders();
var imageCodecInfo = encoders.FirstOrDefault(encoder => encoder.MimeType == "image/tiff");
if (imageCodecInfo == null)
return;
var imageEncoderParams = new EncoderParameters(1);
imageEncoderParams.Param[0] = new EncoderParameter(Encoder.Quality, 100L);
image.Save(@"Test.png", imageCodecInfo, imageEncoderParams);
TIFF 文件大小为 46.8 MB(49,161,628 字节),使用此代码制作的 PNG 为 46.8 MB(49,081,870 字节),但如果我使用 MS 绘制,PNG 文件大小为 6.69 MB(7,021,160 字节)。
那么我应该在代码中进行哪些更改才能获得与使用 MS Paint 相同的压缩效果?
【问题讨论】:
C#: Seeking PNG Compression algorithm/library的可能重复 【参考方案1】:没有好的Minimal, Complete, and Verifiable code example,就不可能确定。但是……
您发布的代码似乎正在获取 TIFF 编码器,而不是 PNG 编码器。仅仅因为您命名带有“.png”扩展名的文件并不意味着您将获得 PNG 文件。决定实际文件格式的是编码器。
如果您使用 TIFF 编码器,您将获得一个与您开始使用的 TIFF 文件大小完全相同的文件。
请尝试:
var imageCodecInfo = encoders.FirstOrDefault(encoder => encoder.MimeType == "image/png");
请注意,这可能会或可能不会让您获得与 Paint 使用的完全相同的压缩。 PNG 有各种各样的压缩“旋钮”来调整其压缩的确切方式,并且您无法通过 .NET API 访问其中的大多数。 Paint 可能使用也可能不使用与您的 .NET 程序相同的值。但您至少应该获得类似级别的压缩。
【讨论】:
这看起来是真正的原因。可以控制比率/速度权衡的质量设置永远不会产生如此巨大的差异,即使它被实施。一些链接似乎表明质量可能已经从 .Net 2 到 4 到 4.5,顺便说一句.. @TaW:我的想法也是如此。不幸的是,似乎 GDI+ 和 WPF API(使用 WIC 进行位图编码)都没有提供一种方法来控制 PNG 格式的任何编码器设置。 :( 但即使是默认算法也会在一定程度上压缩图像,这在 OP 的情况下不会发生。 通过将“image/tiff”更改为“image/png”,文件大小现在为 29.5 MB(31,014,574 字节)。那么.NET 中没有任何方法可以控制 PNG 压缩吗?我还是 C# 的新手,所以请多多包涵。 @New: “.NET 中真的没有任何方法可以控制 PNG 压缩吗?” -- 不容易,不。您可以编写自己的 PNG 包装器(例如调用 WIC 或 libpng),或使用第三方 PNG 库。就您获得的结果而言,请记住,TIFF 也可能已经使用一种特定于 TIFF 的压缩格式进行了压缩。因此,您获得的大小减少 33% 可能与使用无损编解码器所获得的一样好(您说您从 Paint 中获得了更好的结果,但我们不确定您保存的格式) .不能肯定地说没有实际的 TIFF 文件本身。 我真的不想使用任何第三方解决方案,但看起来这就是我必须要做的。至于绘画,我所做的只是打开 TIFF 文件并将其保存为 PNG。【参考方案2】:好的,经过多次反复试验,我想出了这个。
var image = Image.FromFile(@"Test.tiff");
Bitmap bm = null;
PictureBox pb = null;
pb = new PictureBox();
pb.Size = new Size(image.Width, image.Height);
pb.Image = image;
bm = new Bitmap(image.Width, image.Height);
ImageCodecInfo png = GetEncoder(ImageFormat.Png);
EncoderParameters imageEncoderParams = new EncoderParameters(1);
imageEncoderParams.Param[0] = new EncoderParameter(Encoder.Quality, 100L);
pb.DrawToBitmap(bm, pb.ClientRectangle);
bm.Save(@"Test.png", png, encodePars);
pb.Dispose();
并将其添加到我的代码中。
private ImageCodecInfo GetEncoder(ImageFormat format)
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
foreach (ImageCodecInfo codec in codecs)
if (codec.FormatID == format.Guid)
return codec;
return null;
通过将 TIFF 加载到 PictureBox 中,然后将其保存为 PNG,输出的 PNG 文件大小为 7.64 MB(8,012,608 字节)。 Witch 比 Paint 大一点,不过没关系。
【讨论】:
以上是关于c#当将TIFF转换为PNG时,我如何获得与使用MS Paint相同的压缩的主要内容,如果未能解决你的问题,请参考以下文章
将不同的图片格式(jpg、gif、png等)转换为TIFF格式
Ghostscript - EPS(带有透明背景的嵌入式 TIFF)到 PNG 转换