在网上有很多使用 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 库上传

上一篇实现了图片的压缩函数。现在如果需要对图片进行压缩,可以调用实现的函数进行压缩:

pngquant_compress('elephant.png', force=True, quality=20)

但是每次输入 python run_script.py 没有对应的参数传入, 还要去改脚本参数挺麻烦的。为了使用起来更方便,可以添加命令行的方式进行调用:

python run_script.py elephant.png --force --quality 30

python 的 click 库可以非常方便的实现命令行调用。 click 是 flask 作者开发的。用法很简单,只需要添加装饰器在需要运行的程序上就可以了:

image.png

当我输入 python demo.py --help 的时候, 会显示命令行帮助信息:

image.png

click 必填参数 argument

可以在函数上添加 @click.argument('arg_name')

import click
@click.argument("arg_name")
def pngquant_compress():

当程序没有填入必填参数时,将会提示:

image.png

click 可选参数 option

option 是 click 的重点,比 argument 要灵活很多。他的表示方法和 argument 差不多:

import click
@click.option("--force")
def pngquant_compress():
    pass

如果想用多个名称同时表示一个参数,只需要继续在 option 方法中添加位置参数, 就可以通过 -f, --violent 的形式 传入可选参数:

import click
@click.option("--force", "-f", "--violent")
def pngquant_compress():
    pass

如果不想以 --force value 的形式传入值,也可以直接通过 flag 形式,不传入任何值:

import click
@click.option("--force", "-f", "--violent", is_flag=True)
def pngquant_compress():
    pass

显示提示信息:

import click
@click.option(
    "--force", "-f", "--violent", 
    is_flag=True,
    help="强制执行"
    )
def pngquant_compress():
    pass

参数类型限制

比如 quality 参数传入的可以是数字 20, 也可以是 20-30 这种形式。这时候需要自定义一种数据类型进行校验。

class QualityInteger(click.ParamType):
    name = "QualityInteger"     def convert(self, value, param, ctx):
        if value.isdigit():
            return int(value)
        try:
            min_v, max_v = value.split('-')
            int(min_v), int(max_v)
            return value
        except ValueError:
            self.fail('参数不符合类似 20-30 或者 30 的规范')

此时如果输入的参数没有通过检验,命令行会提示错误:

\picom>python demo_06_封装成命令行.py elephant.png -q 20-4a
Usage: demo_06_封装成命令行.py [OPTIONS] FP Error: Invalid value for "--quality" / "-q": 参数不符合类似 20-30 或者 30 的规范

setuptools 打包

from setuptools import setup, find_packages

setup(
    name='picom',
    version='0.1',
    install_requires=[
        'Click',
        'requests'
    ],
)

setup.cfg 配置文件:

[metadata]
name = picom
description = A app to compress images. [options]
packages = find:
package_dir = = src
include_package_data = true
python_requires = >= 3.6 [options.packages.find]
where = src [options.entry_points]
console_scripts =
picom = picom.cli:cli

把 picom 模块放入依赖包路径,执行 pip install --editable . 可以安装这个模块。 安装完成以后,可以在 python 解释器路径看到 picom.exe 命令行文件。建议创建虚拟环境安装,以免对系统环境造成污染。

image.png

撤销 pngquant 全局变量,改由 picom 包内调用

之前在 pngquant_compress 函数中使用 pngquant 命令行是采用环境变量,现在既然是通过 picom 命令去执行,就可以把 pngquant 的环境变量去掉。

首先需要在 picom 包中添加一个 ext 的包存放 pngquant 的执行文件。

修改原来的调用函数:

# pngquant.py

# 原来的写法
command = f'pngquant {fp} --skip-if-larger {force_command} {quality_command}' # 新写法,直接调用 ext/ 下的可执行文件,而不是环境变量中的 pngquant
pngquant_cmd = Path(__file__).resolve().parent / 'ext' / 'pngquant'
command = f'{pngquant_cmd} {fp} --skip-if-larger {force_command} {quality_command}'

总结

通过 click 库和 setuptool 打包,picom 压缩工具使用变得比较简单:

picom elephant.png

开发一款图片压缩工具(三):使用 click 实现命令行的更多相关文章

  1. 尝试用python开发一款图片压缩工具1:尝试 pillow库

    开发目的 我经常使用图片.公众号文章发文也好,还是生活中要使用素材.图片是一种比文字更加直观的载体.但是图片更加占用带宽,很多软件都对图片有大小限制.图片太大也会影响加载速度.我试过几款图片压缩工具, ...

  2. 开发一款图片压缩工具(二):使用 pngquant 实现图片压缩

    上一篇我尝试使用了 pillow 库对 png 图片进行了压缩,效果不好.这次我换用 pngquant 来压缩.pngquant 是用于 PNG 图像有损压缩的命令行实用程序和库.压缩程序会显著减小文 ...

  3. python 开发一款图片压缩工具(四):上传图床

    上一篇使用了 pngquant 图片压缩工具进行压缩,并通过 click 命令行工具构建了 picom 包.这篇的主要功能是实现图片上传. 图片上传功能的实现 通过 pngquant 压缩图片后,得到 ...

  4. 解放双手!推荐一款 GitHub 星标 8.2k+的命令行软件管理器,非常酷炫!

    小二是公司新来的实习生,之前面试的过程中对答如流,所以我非常看好他.第一天,我给他了一台新电脑,要他先在本地搭建个 Java 开发环境. 二话不说,他就开始马不停蹄地行动了.真没想到,他竟然是通过命令 ...

  5. 分享一下怎么开发一款图片视频类App,秒拍和prisma

    第一步,分解短视频App的功能 我们在秒拍官网看到如此描述: [视频拍摄及导入]支持直接拍摄及导入手机本地的视频 [照片电影]照片专属特效,轻松创作照片电影 [MV特效]10余款全新MV特效,让普通视 ...

  6. ROS大型工程学习(三) ROS常用命令行

    1.rosbag 对ros包进行操作的命令. (1)录制包: rosbag record -a //录制数据包,所有topic都录制 rosbag record /topic_name1 /topic ...

  7. 《Java从入门到失业》第二章:Java环境(三):Java命令行工具

    2.3Java命令行工具 2.3.1编译运行 到了这里,是不是开始膨胀了,想写一段代码来秀一下?好吧,满足你!国际惯例,我们写一段HelloWorld.我们在某个目录下记事本,编写一段代码如下: 保存 ...

  8. C# 动态生成word文档 [C#学习笔记3]关于Main(string[ ] args)中args命令行参数 实现DataTables搜索框查询结果高亮显示 二维码神器QRCoder Asp.net MVC 中 CodeFirst 开发模式实例

    C# 动态生成word文档 本文以一个简单的小例子,简述利用C#语言开发word表格相关的知识,仅供学习分享使用,如有不足之处,还请指正. 在工程中引用word的动态库 在项目中,点击项目名称右键-- ...

  9. 介绍一款好用的命令行工具Cmder

    一.Cmder的介绍: 在大多数情况下,我们都想复制命令行窗口中的命令行,但是cmd复制粘贴大家都懂得:有没有更好的工具替代呢? 答案是肯定的,今天我将为大家介绍一款工具--Cmder. Cmder可 ...

随机推荐

  1. 从零开始发布一个ArcGIS Server地图服务

    @ 目录 一.软件环境搭建 1.数据库安装 1.1.Oracle(可选) 1.1.1.安装Oracle服务端 1.1.2.安装Oracle客户端 1.2.PostgreSQL(可选) 1.2.1.安装 ...

  2. Python第十章-模块和包

    模块和包 我们以前的代码都是写在一个文件中, 而且代码也比较短. 假设我们现在要写一个大的系统, 不可能把代码只写到一个文件中, 迫切想把代码写到不同的文件中, 并且能够在一个文件使用另一个文件中代码 ...

  3. 使用charAt()方法查找字符串

    <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8 ...

  4. 面向对象(OO)第一阶段学习总结

    前言:对OO本阶段作业情况说明 本阶段一共完成三次作业,第一次主要是在主方法里面进行编程,也就是和之前C差不多,而随着学习的深入,慢慢了解到面向对象与面向过程的区别.作业的难度也在慢慢增大,后两次都用 ...

  5. [codevs2597]团伙<并查集>

    题目描述 Description 1920年的芝加哥,出现了一群强盗.如果两个强盗遇上了,那么他们要么是朋友,要么是敌人.而且有一点是肯定的,就是: 我朋友的朋友是我的朋友: 我敌人的敌人也是我的朋友 ...

  6. Nutch & Solr & IKAnalyzer Deployment Debug

    Nutch配置错误 (1) IO错误   记得出错的时候把出错的目录删除,否则下次还是出错. (2) Command crawl is deprecated, please use bin/crawl ...

  7. O - 推箱子 HDU - 1254(bfs_box + bfs_man)

    O - 推箱子 HDU - 1254 推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不能 ...

  8. js之:漂浮线

    (function initJParticle( $ ){ "use strict"; var createParticlesSandbox, Utils; Utils = {}; ...

  9. 如何优雅的将文件转换为字符串(环绕执行模式&行为参数化&函数式接口|Lambda表达式)

    首先我们讲几个概念: 环绕执行模式: 简单的讲,就是对于OI,JDBC等类似资源,在用完之后需要关闭的,资源处理时常见的一个模式是打开一个资源,做一些处理,然后关闭资源,这个设置和清理阶段类似,并且会 ...

  10. Spring (五):AOP

    本文是按照狂神说的教学视频学习的笔记,强力推荐,教学深入浅出一遍就懂!b站搜索狂神说或点击下面链接 https://space.bilibili.com/95256449?spm_id_from=33 ...