在網上有很多使用 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