C# nQuant.NET 使用调色板压缩PNG文件

项目用到截屏,然后把图片存储到数据库中。一开始使用的是C#内置的PNG输出方式(GDI+),截屏分辨率大约是780x340,文件大小约40K,看起来还可以,但时间一长,数据库会变得很大,给存储和备份都造成麻烦。

截屏目的只是为了以后可能用来排除错误,所以清晰度基本没要求,能看到大概就行。试了下JPGE编码,图像质量调到60,文件大小约30K,是小了一些。

突然想起来有个TinyPNG的在线工具,把文件下载下来,扔上去,TinyPNG给压缩出来一个10K多点的文件。不甘心,于是开始搜索起来TinyPNG类似算法的解决方案。

TinyPNG的算法说起来也简单,就是将24bit的图片转为8bit的调色板图片,然后使用抖动算法尽量还原图片信息。这里生成调色板及抖动算法是关键,调色板生成的不好,最终图片杂色、条纹就会明显。

找到一个名为nQuant.NET的库,在nuget上就有,于是安装上进行了一下测试。
库的使用也很简单

var quantizer = new nQuant.WuQuantizer();
using (var quantized = quantizer.QuantizeImage(argbImage, 10, 70))
{
    using (var ms = new MemoryStream())
    {
        quantized.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
        data = ms.ToArray();
    }
}

注意这个库只接受32bit,也就是ARGB图片作为输入。

经测试同样的图片,经nQuant处理后大小约为13KB,略大于TinyPNG处理的,也很不错了,比原来小了一半多。或许换一个更好的PNG编码器可以进一步减小体积。