Files
ws2/utils/png_to_jpg.py
2026-01-29 15:32:26 +08:00

177 lines
5.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import os
import sys
from PIL import Image
def png_to_jpg(input_dir=None, bg_color=(0, 0, 0), quality=100):
"""
将指定目录下的所有PNG图片转换为JPG格式
Args:
input_dir: 输入目录,默认为当前目录
bg_color: 背景颜色,默认为黑色(0, 0, 0)
quality: JPG质量默认为100
"""
# 如果未指定输入目录,使用当前目录
if input_dir is None:
input_dir = os.getcwd()
# 确保目录存在
if not os.path.exists(input_dir):
print(f"错误: 目录 '{input_dir}' 不存在")
return False
# 获取所有PNG文件
png_files = [f for f in os.listdir(input_dir) if f.lower().endswith('.png')]
if not png_files:
print(f"在目录 '{input_dir}' 中未找到PNG文件")
return True
print(f"找到 {len(png_files)} 个PNG文件")
# 转换每个PNG文件
successful = 0
failed = 0
for png_file in png_files:
try:
# 构建完整的文件路径
png_path = os.path.join(input_dir, png_file)
# 打开PNG图像
img = Image.open(png_path)
# 如果图像有alpha通道透明通道处理透明部分
if img.mode in ('RGBA', 'LA', 'P'):
# 创建新的RGB图像背景为指定颜色
rgb_img = Image.new('RGB', img.size, bg_color)
# 如果是P模式调色板先转换为RGBA
if img.mode == 'P':
img = img.convert('RGBA')
# 将原图像粘贴到新背景上
if img.mode == 'RGBA':
# RGBA图像需要分离alpha通道
rgb_img.paste(img, mask=img.split()[3]) # 使用alpha通道作为蒙版
elif img.mode == 'LA':
# LA模式L是亮度A是alpha
rgb_img.paste(img.convert('RGBA'), mask=img.split()[1])
else:
# 如果没有alpha通道直接转换为RGB
rgb_img = img.convert('RGB')
# 生成输出文件名(将.png替换为.jpg
jpg_file = os.path.splitext(png_file)[0] + '.jpg'
jpg_path = os.path.join(input_dir, jpg_file)
# 保存为JPG
rgb_img.save(jpg_path, 'JPEG', quality=quality, optimize=True)
print(f"✓ 转换成功: {png_file} -> {jpg_file}")
successful += 1
except Exception as e:
print(f"✗ 转换失败 {png_file}: {str(e)}")
failed += 1
print(f"\n转换完成: 成功 {successful} 个, 失败 {failed}")
return failed == 0
def main():
"""主函数,处理命令行参数"""
import argparse
parser = argparse.ArgumentParser(
description='将PNG图片转换为JPG格式透明背景转为指定颜色',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
示例:
%(prog)s # 转换当前目录所有PNG黑色背景质量100
%(prog)s -d /path/to/images # 转换指定目录
%(prog)s -c white -q 90 # 白色背景质量90
%(prog)s -c 255,255,255 # 使用RGB值指定白色背景
"""
)
parser.add_argument(
'-d', '--directory',
default='.',
help='输入目录,默认为当前目录'
)
parser.add_argument(
'-c', '--color',
default='black',
help='背景颜色支持颜色名或RGB值"white""255,255,255"默认为black'
)
parser.add_argument(
'-q', '--quality',
type=int,
default=100,
choices=range(1, 101),
metavar='[1-100]',
help='JPG质量1-100默认为100'
)
parser.add_argument(
'-r', '--recursive',
action='store_true',
help='递归处理子目录(注意:本脚本当前版本不支持,已预留接口)'
)
args = parser.parse_args()
# 解析颜色参数
bg_color = (0, 0, 0) # 默认黑色
if args.color:
color_str = args.color.lower().strip()
# 预定义颜色
color_map = {
'black': (0, 0, 0),
'white': (255, 255, 255),
'red': (255, 0, 0),
'green': (0, 255, 0),
'blue': (0, 0, 255),
'transparent': None,
}
if color_str in color_map:
bg_color = color_map[color_str]
elif ',' in color_str:
# 尝试解析RGB值
try:
rgb = [int(x.strip()) for x in color_str.split(',')]
if len(rgb) == 3 and all(0 <= x <= 255 for x in rgb):
bg_color = tuple(rgb)
else:
print(f"警告: 颜色值无效,使用默认黑色")
except ValueError:
print(f"警告: 颜色格式无效,使用默认黑色")
else:
print(f"警告: 颜色 '{args.color}' 不被识别,使用默认黑色")
print(f"设置:")
print(f" 目录: {args.directory}")
print(f" 背景色: RGB{bg_color}")
print(f" 质量: {args.quality}")
print(f" 递归: {'' if args.recursive else ''}")
print("-" * 40)
# 执行转换
try:
success = png_to_jpg(args.directory, bg_color, args.quality)
return 0 if success else 1
except KeyboardInterrupt:
print("\n操作被用户中断")
return 130
except Exception as e:
print(f"错误: {str(e)}")
return 1
if __name__ == "__main__":
sys.exit(main())