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相同的压缩的主要内容,如果未能解决你的问题,请参考以下文章

使用 CMYK 和透明度将 PDF 转换为 Tiff

在.Net中将TIFF文件转换为PNG

将不同的图片格式(jpg、gif、png等)转换为TIFF格式

Ghostscript - EPS(带有透明背景的嵌入式 TIFF)到 PNG 转换

到作地于出JPG,BMP,PNG,TIFF转换为PDF七海地

tiff格式如何转换成jpg格式