Tinypng 是一个在线 png 压缩工具

FFmpeg 下载地址

原图 903 kb

原图 903 kb

Tinypng压缩过的 96KB

Tinypng压缩过的 96KB

目标就是用 FFmpeg 做到近似 Tinypng 的处理效果

首先是判断颜色格式 这里我提前做好了准备 原图的rgb24 输出是 pal8 也就是输入 24位 输出256色

如果不清楚 可以用下面的命令来输出一个log看一眼

ffprobe -hide_banner -v quiet -print_format json -show_format -show_streams in.png > in.log

in.log文件中 “pix_fmt”: “pal8”, 这个就是对应的色彩

直接转换

ffmpeg -hide_banner -i in.png -pix_fmt pal8 out_1.png

颗粒感很厚重 而且体积也不小 123 KB

颗粒感很厚重 而且体积也不小 123 KB

效果看起来很差,于是我想到了降噪

ffmpeg -hide_banner -i in.png -pix_fmt pal8  -vf dctdnoiz=4.5 -y out_2.png

2D DCT降噪 但好像没什么效果 看来原因并不是这样的 124 KB

但好像没什么效果  看来原因并不是这样的 124 KB

我尝试调整了多种降噪和dither参数,但是效果都很惨。这里就不细说了看起来问题并不是出在内容上面,应该是思路有错误。

后来友人提醒:

我看了下圖像信息 不會是因爲調色板吧? 統計一下,第一張圖用到了256色 第二張衹有133 那麽就是第一張圖用了調色板來映射256色 而第二張就是老老實實地按照原本的256色來 其實gif就是這樣的 通過調色板來映射256色,所以能勉强達到一個能接受的效果

好吧 看来需要优化一下调色板

优化

ffmpeg -i in.png -vf palettegen=max_colors=256:stats_mode=single -y out_3.png

这里的输出结果是一个调色板 并不是完整图像 由于这是单张静图所以mode使用的是single ; 这个参数有几种具体区别可以看文档 http://ffmpeg.org/ffmpeg-all.html#palettegen-1

再用优化过的调色板去转换 得到结果 116 KB

ffmpeg -i in.png -i out_3.png -lavfi "[0][1:v] paletteuse" -pix_fmt pal8 -y out_4.png

结果 116 KB

至此,效果上已经可以接受了但是体积还差 10KB 的差距,我还是搞不清楚差距在哪里。 如果有人知道希望可以指导一下