[python]png转webp的命令行工具

news/2025/2/4 15:53:37/文章来源:https://www.cnblogs.com/XY-Heruo/p/18698255

前言

网页上使用webp格式的图片更加省网络流量和存储空间,但本地图片一般是png格式的,所以考虑用python的pillow库将png格式的图片转换为webp格式。

需求:

  • 可以在系统任意地方调用。这需要编译成二进制程序或写成脚本放到PATH环境变量下
  • 支持指定图片文件输入目录。默认为当前目录。
  • 支持指定图片文件输出目录。默认为输入文件的同级目录。
  • 支持指定图片压缩质量。默认为80。需要校验传参。
  • 支持并发同时压缩多个图片文件。默认为串行。传参的并发数最大为CPU核心数。

代码

from PIL import Image
import argparse
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor
import os
from time import timedef 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为WEBPArgs:input_path (Path): 输入文件路径output_path (Path): 输出文件路径, 可以是一个目录, 也可以是一个webp文件的路径quality (int, optional): 图片压缩质量. 默认为 80."""# 如果quality不在0到100之间, 则设置为80if 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# 如果指定了输出目录, 则修改输出文件名为为输入文件名, 并修改扩展名为.webpif output_path.suffix.lower() != ".webp":output_path = output_path / input_path.with_suffix(".webp").namestart = 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 Nonemax_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 Nonefor 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,如果要在其它位置调用这个脚本,个人想了两种方式:

  1. 另外编写一个shell脚本,如果是windows,则编写powershell脚本,在这个脚本内编写调用逻辑,并把这个脚本放到PATH环境变量的路径下。
  2. 编译成二进制文件,将编译好的二进制文件放到PATH环境变量下。这比较方便发送给别人,这样别人就不需要在电脑上安装python环境。

这里用pyinstaller将程序编译成二进制文件,尽量在python虚拟环境下编译,以减小二进制文件的体积

  1. 创建虚拟环境
python -m venv png2webp
  1. 激活虚拟环境
# linux
cd png2webp
source ./bin/activate# windows powershell
cd png2webp
.\Scripts\activate
  1. 安装依赖
python -m pip install pillow pyinstaller
  1. 编译。注意修改实际的python文件路径。
pyinstaller -F --clean .\main.py
  1. 生成的二进制文件在当前目录下的dist目录,将其放置到PATH环境变量下,如有需要可重命名。
  2. 测试在其他目录下调用
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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/878607.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025 PVC

短线有波上涨

静态代理模式:代码世界的“替身演员”

静态代理是代理模式的一种**实现方式**,其特点是**代理类在编译时就已经确定**,代理类的代码是在程序编译阶段生成的,而不是运行时动态生成。一、关于静态代理 1.1 简介 静态代理是代理模式的一种实现方式,其特点是代理类在编译时就已经确定,代理类的代码是在程序编译阶段…

一个 .NET 开源、免费、功能强大的Windows应用卸载神器

前言 今天大姚给大家分享一个基于 .NET 开源(Apache License)、免费、功能强大的Windows应用卸载神器:Bulk Crap Uninstaller。 项目介绍 Bulk Crap Uninstaller 是一款基于 .NET 开源(Apache License)、免费、功能强大的Windows应用卸载工具,旨在帮助用户快速且有效地移…

强化学习驱动的自适应模型选择与融合用于监督学习

图片来源:Unsplash 上的 Agence Olloweb引言 机器学习模型的选择一直是一个挑战。无论是预测股票价格、诊断疾病,还是优化营销活动,问题始终是:哪个模型最适合我的数据? 传统上,我们依赖交叉验证来测试多个模型——XGBoost、LGBM、随机森林等——然后根据验证性能选择最佳…

Python 与 PostgreSQL 集成:深入 psycopg2 的应用与实践

title: Python 与 PostgreSQL 集成:深入 psycopg2 的应用与实践 date: 2025/2/4 updated: 2025/2/4 author: cmdragon excerpt: PostgreSQL 作为开源关系型数据库的佼佼者,因其强大的功能与性能被广泛应用于各种项目中。而 Python 则因其简洁易用的语法、丰富的库和强大的数…

Gitea Enterprise 23.0.0 (Linux, macOS, Windows) - 本地部署的企业级 Gti 服务

Gitea Enterprise 23.0.0 (Linux, macOS, Windows) - 本地部署的企业级 Gti 服务Gitea Enterprise 23.0.0 (Linux, macOS, Windows) - 本地部署的企业级 Gti 服务 The Premier Enterprise Solution for Self-Hosted Git Service 请访问原文链接:https://sysin.org/blog/gitea/…

【跟着阿舜学音乐-笔记】2.4电鼓及其他打击乐器

2.4电鼓及其他打击乐器 滚镲:使用滚奏的方式打击吊镲(由弱到强不断打击在自然地由强到弱) 2.4.1电鼓 电鼓分为两种来源,一种为合成器合成,另一种则是由架子鼓发出后进行电声的处理。 电鼓的军鼓会稍显薄弱,有时由采取再垫一轨的方式。此外,电鼓的踩镲在一些风格曲目中打…

[Nuxt] Rendering mode

A Nuxt app can be rendered in various modes. The default standard mode is simply called SSR. Specifically, it means Server-Side Rendering on request. “on request” means whenever the user clicks on an external link or enters a URL in the address bar to ac…

ASP.NET Core 中,认证(Authentication)和授权(Authorization)

在 ASP.NET Core 中,认证(Authentication)和授权(Authorization)是两个非常重要的概念。它们确保用户能够安全地访问应用程序,并且在访问过程中能按其权限被正确地控制。接下来,我将详细解释这两个概念,并且如何在 ASP.NET Core 中实现它们。 1. 认证(Authentication)…

ASP.NET Core 中,Cookie 认证在集群环境下的应用

在 ASP.NET Core 中,Cookie 认证在集群环境下的应用通常会遇到一些挑战。主要的问题是 Cookie 存储在客户端的浏览器中,而认证信息(比如 Session 或身份令牌)通常是保存在 Cookie 中,多个应用实例需要共享这些 Cookie 信息,以便用户在集群中各个实例间无缝切换。 1. 集群…

ASP.NET Core 中使用 Cookie 身份验证

在 ASP.NET Core 中使用 Cookie 身份验证,通常是为了实现用户的登录和授权。以下是配置 Cookie 身份验证的步骤。 1. 安装必要的 NuGet 包 首先,确保项目中包含 Microsoft.AspNetCore.Authentication.Cookies 包。你可以通过 NuGet 包管理器或命令行安装它: dotnet add pack…

GDB调试(一)

GDB调试 GDB简介 GDB的功能 GDB(GNU Debugger)是用于调试 C、C++ 等语言的强大工具。它允许开发者执行以下操作:启动程序并按照预期条件暂停(如断点处)。 检查程序中的变量和内存状态。 单步执行代码,观察每一步的变化。 修改运行中的变量值以测试不同的假设。 调试程序崩…