网页上使用webp格式的图片更加省网络流量和存储空间,但本地图片一般是png格式的,所以考虑用python的pillow库将png格式的图片转换为webp格式。
需求:
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 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 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,如果要在其它位置调用这个脚本,个人想了两种方式:
PATH
环境变量的路径下。PATH
环境变量下。这比较方便发送给别人,这样别人就不需要在电脑上安装python环境。这里用pyinstaller
将程序编译成二进制文件,尽量在python虚拟环境下编译,以减小二进制文件的体积
python -m venv png2webp
# linux
cd png2webp
source ./bin/activate
# windows powershell
cd png2webp
.Scriptsactivate
python -m pip install pillow pyinstaller
pyinstaller -F --clean .main.py
dist
目录,将其放置到PATH
环境变量下,如有需要可重命名。png2webp --help
# 直接执行, 默认转换当前目录下的所有png文件到同级目录
png2webp
# 将转换后的webp文件保存到output目录下
png2webp -o output
# 转换单个png文件, 单独转换时不支持指定输出目录
png2webp -f 1.png
# 同时转换, -t 指定最大并发数, 默认为1, 最大不得超过CPU核心数
png2webp -t 2
# 指定图片压缩质量, 默认为80, 取值区间为[0, 100], 值越高, 质量越好, 生成图片体积越大
png2webp -q 75
本文来自博客园,作者:花酒锄作田,转载请注明原文链接:https://www.cnblogs.com/XY-Heruo/p/18698255
参与评论
手机查看
返回顶部