基于Python实现png转webp的命令行工具!
基于Python实现png转webp的命令行工具!
网页上使用webp格式的图片更加省网络流量和存储空间,但本地图片一般是png格式的,所以本文就来为大家介绍一下如何使用Python实现png转webp功能吧。
前言
网页上使用webp格式的图片更加省网络流量和存储空间,但本地图片一般是png格式的,所以考虑用python的pillow库将png格式的图片转换为webp格式。
需求:
- 可以在系统任意地方调用。这需要编译成二进制程序或写成脚本放到PATH环境变量下
- 支持指定图片文件输入目录。默认为当前目录。
- 支持指定图片文件输出目录。默认为输入文件的同级目录。
- 支持指定图片压缩质量。默认为80。需要校验传参。
- 支持并发同时压缩多个图片文件。默认为串行。传参的并发数最大为CPU核心数。
代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
from PIL import Image import argparse from pathlib import Path from concurrent.futures import ThreadPoolExecutor import os from time import time def parse_args(): """解析命令行参数""" parser = argparse.ArgumentParser(description = "Convert PNG to WEBP" , usage = """ # 直接执行, 默认转换当前目录下的所有png文件到同级目录 python main.py # 将转换后的webp文件保存到output目录下 python main.py -o output # 转换单个png文件, 单独转换时不支持指定输出目录 python main.py -f 1.png # 同时转换, -t 指定最大并发数, 默认为1, 最大不得超过CPU核心数 python main.py -t 2 # 指定图片压缩质量, 默认为80, 取值区间为[0, 100], 值越高, 质量越好, 生成图片体积越大 python main.py -q 75 """ ) parser.add_argument( "-i" , type = str , default = os.getcwd(), help = "Path to the input PNG image" ) parser.add_argument( "-o" , type = str , default = os.getcwd(), help = "Path to the output WEBP image" ) parser.add_argument( "-f" , type = str , default = " ", help=" specific file name") parser.add_argument( "-t" , type = int , default = 1 , help = "Number of threads to use" ) parser.add_argument( "-q" , type = int , default = 80 , help = "Quality of the output WEBP image" ) return parser.parse_args() def convert_png_to_webp(input_path: Path, output_path: Path, quality = 80 ) - > None : """ 转换PNG为WEBP Args: input_path (Path): 输入文件路径 output_path (Path): 输出文件路径, 可以是一个目录, 也可以是一个webp文件的路径 quality (int, optional): 图片压缩质量. 默认为 80. """ # 如果quality不在0到100之间, 则设置为80 if quality > 100 or quality < 0 : print ( "quality must be between 0 and 100, now set to 80" ) real_q = quality if quality < = 100 and quality > 0 else 80 # 如果输入文件不存在, 则打印错误信息并返回 if not input_path.exists(): print (f "input file {input_path} not found" ) return # 如果指定了输出目录, 则尝试创建输出目录 if not output_path.exists() and output_path.suffix.lower() ! = ".webp" : try : output_path.mkdir(parents = True ) except Exception as e: print (e) print ( "Failed to create output directory" ) return # 如果指定了输出目录, 则修改输出文件名为为输入文件名, 并修改扩展名为.webp if output_path.suffix.lower() ! = ".webp" : output_path = output_path / input_path.with_suffix( ".webp" ).name start = time() try : with Image. open (input_path) as img: print ( f "Converting {input_path}, quality={real_q}, size: {input_path.stat().st_size / 1024:.2f}KB" ) img.save(output_path, "WEBP" , quality = real_q) print ( f "Convert png2webp successfully, output file: {output_path.name}, size: {int(output_path.stat().st_size) / 1024:.2f}KB, elapsed time: {time() - start:.2f}s" ) except Exception as e: print (f "Convert png2webp failed: {e}" ) def multi_thread_convert(max_workers: int , input_path, output_path, quality) - > None : """并发转换png为webp""" print (f "convert png to webp with multi threads, max_workers: {max_workers}" ) p = Path(input_path) op = Path(output_path) if output_path ! = os.getcwd() else None max_workers = max_workers if max_workers < os.cpu_count() else os.cpu_count() with ThreadPoolExecutor(max_workers = max_workers) as executor: for f in p.glob( "**/*.png" ): executor.submit( convert_png_to_webp, f, op or f.with_suffix( ".webp" ), quality ) def main(): start = time() args = parse_args() if not args.f: if args.t > 1 : multi_thread_convert(args.t, args.i, args.o, args.q) else : p = Path(args.i) op = Path(args.o) if args.o ! = os.getcwd() else None for f in p.glob( "**/*.png" ): convert_png_to_webp(f, op or f.with_suffix( ".webp" ), args.q) else : p = Path(args.f) convert_png_to_webp(p, p.with_suffix( ".webp" ), args.q) print (f "Finished! Total elapsed time: {time() - start:.2f}s" ) if __name__ = = "__main__" : main() |
编译
因为是在python虚拟环境中安装的pillow,如果要在其它位置调用这个脚本,个人想了两种方式:
- 另外编写一个shell脚本,如果是windows,则编写powershell脚本,在这个脚本内编写调用逻辑,并把这个脚本放到
PATH
环境变量的路径下。 - 编译成二进制文件,将编译好的二进制文件放到
PATH
环境变量下。这比较方便发送给别人,这样别人就不需要在电脑上安装python环境。
这里用pyinstaller
将程序编译成二进制文件,尽量在python虚拟环境下编译,以减小二进制文件的体积
1.创建虚拟环境
1
|
python - m venv png2webp |
2.激活虚拟环境
1
2
3
4
5
6
7
|
# linux cd png2webp source . /bin/activate # windows powershell cd png2webp .\Scripts\activate |
3.安装依赖
1
|
python -m pip install pillow pyinstaller |
4.编译。注意修改实际的python文件路径。
1
|
pyinstaller -F --clean .\main.py |
5.生成的二进制文件在当前目录下的dist
目录,将其放置到PATH
环境变量下,如有需要可重命名。
6.测试在其他目录下调用
1
|
png2webp --help |
使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
# 直接执行, 默认转换当前目录下的所有png文件到同级目录 png2webp # 将转换后的webp文件保存到output目录下 png2webp -o output # 转换单个png文件, 单独转换时不支持指定输出目录 png2webp -f 1.png # 同时转换, -t 指定最大并发数, 默认为1, 最大不得超过CPU核心数 png2webp -t 2 # 指定图片压缩质量, 默认为80, 取值区间为[0, 100], 值越高, 质量越好, 生成图片体积越大 png2webp -q 75 |
到此这篇关于基于Python实现png转webp的命令行工具 的文章就介绍到这了。
学习资料见知识星球。
以上就是今天要分享的技巧,你学会了吗?若有什么问题,欢迎在下方留言。
快来试试吧,小琥 my21ke007。获取 1000个免费 Excel模板福利!
更多技巧, www.excelbook.cn
欢迎 加入 零售创新 知识星球,知识星球主要以数据分析、报告分享、数据工具讨论为主;
1、价值上万元的专业的PPT报告模板。
2、专业案例分析和解读笔记。
3、实用的Excel、Word、PPT技巧。
4、VIP讨论群,共享资源。
5、优惠的会员商品。
6、一次付费只需129元,即可下载本站文章涉及的文件和软件。
共有 0 条评论