zoukankan      html  css  js  c++  java
  • 使用 python 压缩 png 图片,高达 80% 压缩率,肉眼无差异(二):使用 pngquant 实现图片压缩

    在网上有很多使用 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 优化后的图片,几乎看不出区别: pngquant effect.jpg

    这是 pillow 同样采用中值切割和 k-means 得到的优化效果, 云彩有明显颜色过渡不自然问题: quantize effect.jpg

    pngquant 压缩库安装

    pngquant 提供了源码、命令行和 GUI 等多种形式。它不是 python 写的,所以只能用 python 调用命令行或者源码函数。 GUI 的工具目前来说还比较难用,并没有命令行方便,而源码形式可以通过 ctype 使用 python语言去调用 c 源码。但是目前对这方面还不怎么了解,可以后面再去使用 so 动态库等方式。

    先用命令行形式进行 PNG 压缩。

    1,下载 windows安装包 或者 mac 和 linux 版本的安装包。

    2,命令行输入 pngquant 就可以使用了;

    3,为了使用方便,可以配置环境变量(后面如果和 picom 集成在了一起再去掉 )。

    pngquant-fs8.pngpngquant-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 真是个不错的工具。

  • 相关阅读:
    Git常用命令总结
    自己动手做一个vue组件,并上传npm
    详解树状结构图 vue-org-tree
    npm依赖之tooljs、requestjs
    本地服务器热更新 插件 live-server
    VUE项目引入第三方依赖报错 Uncaught SyntaxError: Unexpected token <
    npm安装依赖报 npm ERR! code Z_BUF_ERROR npm ERR! errno -5 npm ERR! zlib: unexpected end of file 这个错误解决方案
    关于Vue-$router传参出现刷新页面或者返回页面丢失数据的问题
    Vue自行封装常用组件-倒计时
    Vue自行封装常用组件-文本提示
  • 原文地址:https://www.cnblogs.com/heniu/p/12782209.html
Copyright © 2011-2022 走看看