C#:寻求PNG压缩算法/库

时间:2010-12-11 19:15:30

标签: c# .net algorithm png

我需要压缩或至少降低用户上传到我网站的某些png图像的质量。我已经调整了大小,但这对图像大小没有太大作用。

为.net 4.0或更低版本寻求png /图像压缩或质量损失算法或库。


这是我目前保存/转换图片的方式:

Image mainImg = ImageHelper.ResizeImage(bmp, 600, 500, false);
mainImg.Save(filePath, System.Drawing.Imaging.ImageFormat.Png);

3 个答案:

答案 0 :(得分:23)

不幸的是,.NET(以及构建.NET图形库的GDI +)不支持PNG的任何编码参数。实际上,如果使用PNG编码器Clsid在图像上调用GetEncoderParameterList,则会出现“未实现”异常。

更不幸的是,ImageFormat和ImageCodecInfo都是密封类,你不能只为.NET可以原生访问的内容添加新的编解码器。微软放弃了这个。

这意味着你的选择是按受虐狂的降序排列: 1)在.NET中实现自己的保存功能,实现RFC 2083, 2)实现基于将libpng移植到.NET的保存功能, 3)直接调用从libpng构建的非托管代码

libpng拥有出色的文档,并且在可用性和许可证允许方面都是免费的。

答案 1 :(得分:7)

PNG通常是无损压缩方案,这意味着除非减少像素数(大小)或颜色深度,否则图像质量永远不会降低。有三种方法可以缩小PNG图像的文件大小:

  • 减少像素数(通过缩小图像);这里有明显的解决方案损失
  • 使用不同的预压缩过滤器/ DEFLATE压缩器参数(OptiPNG是我最喜欢的工具,可自动选择过滤器/压缩器设置的最佳组合)
  • 将颜色深度从真彩色减少到256(或更少)颜色将为您节省大量的字节,但通常会以极高的视觉成本(特别是对于摄影图像)

似乎.NET没有内置的方法来更改PNG的预压缩过滤器或压缩器参数,因此您必须使用外部库。 OptiPNG或任何other PNG优化工具都不是本机.NET库,因此您必须处理P /调用库或运行单独的进程来处理每个映像。但是,你经常会节省大约5%或更少的费用(虽然我已经看到多达40%),因为这最终是一个无损的过程。

我建议不要在你描述的自动方案中减少颜色深度,因为结果看起来真的很糟糕(想想旧的抖动GIF)。 (但是,如果您正在进行手动优化,请在Windows上查看Color Quantizer,在Mac上查看ImageAlpha。)

实际上,以质量为代价减少文件大小的最佳方法是转换为JPEG,这不需要外部依赖,并且设计为有损压缩算法:

mainImg.Save(filePath, System.Drawing.Imaging.ImageFormat.Jpeg); // make sure you change `filePath` to end with jpg instead of png.

答案 2 :(得分:0)

不幸的是,.Net的png图像处理器不会对输出进行任何优化启发。最好的办法是在服务器上提供optipng / pngcrush二进制文件,将调整后的输出渲染为临时文件,然后通过System.Diagnostics.Process使用pngcrush。

在大多数情况下,如果上传的是照片且原始格式为JPEG,那么使用JPEG输出效果会更好。