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

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

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


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

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

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

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

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

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

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

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

似乎.NET没有内置的方法来更改PNG的预压缩filter或压缩器参数,因此您必须使用外部库。 OptiPNG或任何其他 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. 

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

在大多数情况下,如果上传是照片而原始格式是JPEG,那么使用JPEG输出可以更好地服务。