在网上有很多使用 python 的 pillow 库进行图片压缩的教程,使用简单,但是压缩效果存在明显的色彩不自然,这是因为 pillow 库采取的压缩算法没有优化的问题。
这个系列实现一款简单的压缩工具,使用 pngquant 有损压缩,压缩率高达 80%, 而且压缩后的图片没有明显差异。
系列文章:
1,使用 python 压缩 png 图片,高达 80% 压缩率,肉眼无差异(一):为什么不用 pillow库.md
2,使用 python 压缩 png 图片,高达 80% 压缩率,肉眼无差异(二):使用 pngquant 实现图片压缩
3,使用 python 压缩 png 图片,高达 80% 压缩率,肉眼无差异(三):使用 click 库实现命令行
4,使用 python 压缩 png 图片,高达 80% 压缩率,肉眼无差异(四):使用 requests 库上传
上一篇我尝试使用了 pillow 库对 png 图片进行了压缩,效果不好。这次我换用 pngquant 来压缩。 pngquant 是用于 PNG 图像有损压缩的命令行实用程序和库。压缩程序会显著减小文件大小(通常高达70%),并保持完全的alpha透明度。通过使用alpha通道将图像转换为更高效的8位PNG格式(通常比24/32位PNG文件小60-80%)。
pngquant 使用的算法主要是中值切割量化算法的改进版和 K-means 颜色校正。得到的图片颜色差异肉眼几乎无法察觉。
这是 pngquant 优化后的图片,几乎看不出区别:
这是 pillow 同样采用中值切割和 k-means 得到的优化效果, 云彩有明显颜色过渡不自然问题:
pngquant 压缩库安装
pngquant 提供了源码、命令行和 GUI 等多种形式。它不是 python 写的,所以只能用 python 调用命令行或者源码函数。 GUI 的工具目前来说还比较难用,并没有命令行方便,而源码形式可以通过 ctype 使用 python语言去调用 c 源码。但是目前对这方面还不怎么了解,可以后面再去使用 so 动态库等方式。
先用命令行形式进行 PNG 压缩。
1,下载 windows安装包 或者 mac 和 linux 版本的安装包。
2,命令行输入 pngquant
就可以使用了;
3,为了使用方便,可以配置环境变量(后面如果和 picom 集成在了一起再去掉 )。
pngquant-fs8.png
快速使用 pngquant
pngquant 图片名称.png
对于一些可选参数的说明:
1,--skip-if-larger
pngquant 有时候压缩的文件会比源文件大。这个选项会判断,如果大就取消执行。强烈建议加上
2,--quality 0-100
图片质量。对于颜色没有特别要求的可以缩减到 10, 但是越小压缩率越低,通常不需要设置。
3,--force
强制执行,pngquant 会判断,如果有一个已经压缩的同名文件在当前文件夹,就不会执行。这个选项会覆盖原来的文件。
4,--output file
指定输入文件的名称。 可以指定为 jpg 格式,但是图片不会变得更小。
5,--speed
执行速度
使用 subprocess 调用 pngquant 命令行
对应的程序:
import subprocess
subprocess.run(\'pngquant elephant.png\')
如果想获取程序运行时屏幕上显示的内容,可以使用 check_output 方法,在这里不需要。
接下来使用 subprocess 封装对应的压缩函数:
def pngquant_compress(fp, force=False, quality=None):
"""压缩函数.
参数:
fp: 文件名称
force: 如果存在同名文件,是否覆盖
quality: 压缩质量。 10-40, or 10
"""
force_command = \'-f\' if force else \'\'
quality_command = \'\'
if quality and isinstance(quality, int):
quality_command = f\'--quality {quality}\'
if quality and isinstance(quality, str):
quality_command = f\'--quality {quality}\'
command = f\'pngquant {fp} --skip-if-larger {force_command} {quality_command}\'
subprocess.run(command)
if __name__ == "__main__":
pngquant_compress(\'elephant.png\', force=True, quality=20)
总结
之前使用大多数教程推荐的 pillow 库,效果并不好。这次换用知名的 pngquant 以后,色彩已经用肉眼很难感知。 要实现对 png 图片的压缩率和图片效果的平衡,pngquant 真是个不错的工具。