基于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

欢迎 加入 零售创新 知识星球,知识星球主要以数据分析、报告分享、数据工具讨论为主;

Excelbook.cn Excel技巧 SQL技巧 Python 学习!

你将获得:

1、价值上万元的专业的PPT报告模板。

2、专业案例分析和解读笔记。

3、实用的Excel、Word、PPT技巧。

4、VIP讨论群,共享资源。

5、优惠的会员商品。

6、一次付费只需129元,即可下载本站文章涉及的文件和软件。

文章版权声明 1、本网站名称:Excelbook
2、本站永久网址:http://www.excelbook.cn
3、本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长王小琥进行删除处理。
4、本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
5、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报。
6、本站资源大多存储在云盘,如发现链接失效,请联系我们我们会第一时间更新。

THE END
分享
二维码
< <上一篇
下一篇>>