1
+ import os
2
+ import sys
3
+ import argparse
4
+ from PIL import Image
5
+ from pathlib import Path
6
+
7
+
8
+ def convert_image (input_path , output_path , format , quality = 85 ):
9
+ """
10
+ 执行图片格式转换
11
+
12
+ 参数:
13
+ input_path: 输入文件路径
14
+ output_path: 输出文件路径
15
+ format: 目标格式 ('webp', 'jpg', 'png')
16
+ quality: 输出质量 (1-100)
17
+ """
18
+ try :
19
+ with Image .open (input_path ) as img :
20
+ # 创建输出目录
21
+ os .makedirs (os .path .dirname (output_path ), exist_ok = True )
22
+
23
+ # 处理透明背景转换
24
+ if format in ('jpg' , 'jpeg' ) and img .mode in ('RGBA' , 'LA' , 'P' ):
25
+ img = img .convert ('RGB' )
26
+
27
+ # 保存为指定格式
28
+ if format == 'webp' :
29
+ img .save (output_path , 'WEBP' , quality = quality , method = 6 )
30
+ elif format == 'jpg' :
31
+ img .save (output_path , 'JPEG' , quality = quality , optimize = True )
32
+ else : # PNG
33
+ img .save (output_path , 'PNG' , optimize = True )
34
+
35
+ return True , ""
36
+
37
+ except Exception as e :
38
+ return False , str (e )
39
+
40
+
41
+ def batch_convert (input_folder , output_folder , operation , format , quality = 85 ):
42
+ """
43
+ 批量转换文件夹中的图片
44
+
45
+ 参数:
46
+ input_folder: 输入文件夹
47
+ output_folder: 输出文件夹
48
+ operation: 转换类型 ('to_webp', 'from_webp')
49
+ format: 目标格式 (当 operation 为 'from_webp' 时使用)
50
+ quality: 输出质量
51
+ """
52
+ # 支持的输入格式
53
+ if operation == 'to_webp' :
54
+ input_extensions = ('.jpg' , '.jpeg' , '.png' , '.JPG' , '.JPEG' , '.PNG' )
55
+ output_extension = '.webp'
56
+ else : # from_webp
57
+ input_extensions = ('.webp' , '.WEBP' )
58
+ output_extension = f'.{ format .lower ()} '
59
+
60
+ # 统计变量
61
+ converted = 0
62
+ skipped = 0
63
+ errors = []
64
+
65
+ print (f"\n { '=' * 50 } " )
66
+ print (f"开始转换: { input_folder } → { output_folder } " )
67
+ print (f"操作类型: { '转 WebP' if operation == 'to_webp' else '转 ' + format .upper ()} " )
68
+ print (f"质量设置: { quality } " )
69
+ print (f"{ '=' * 50 } \n " )
70
+
71
+ # 遍历输入文件夹
72
+ for file in Path (input_folder ).iterdir ():
73
+ if not file .is_file ():
74
+ continue
75
+
76
+ # 检查文件扩展名
77
+ if file .suffix .lower () not in input_extensions :
78
+ skipped += 1
79
+ continue
80
+
81
+ # 构建输出路径
82
+ output_file = Path (output_folder ) / (file .stem + output_extension )
83
+
84
+ # 执行转换
85
+ success , error_msg = convert_image (
86
+ str (file ),
87
+ str (output_file ),
88
+ 'webp' if operation == 'to_webp' else format .lower (),
89
+ quality
90
+ )
91
+
92
+ if success :
93
+ print (f"✓ { file .name } → { output_file .name } " )
94
+ converted += 1
95
+ else :
96
+ print (f"× { file .name } 失败: { error_msg } " )
97
+ errors .append (f"{ file .name } : { error_msg } " )
98
+
99
+ # 打印结果
100
+ print (f"\n { '=' * 50 } " )
101
+ print (f"转换完成!" )
102
+ print (f"- 成功转换: { converted } 个文件" )
103
+ print (f"- 跳过文件: { skipped } 个" )
104
+
105
+ if errors :
106
+ print (f"\n 错误信息 ({ len (errors )} 个错误):" )
107
+ for error in errors :
108
+ print (f" { error } " )
109
+
110
+ print (f"\n 输出位置: { os .path .abspath (output_folder )} " )
111
+ return converted , len (errors )
112
+
113
+
114
+ def main ():
115
+ # 创建命令行解析器
116
+ parser = argparse .ArgumentParser (
117
+ description = "全能图像转换工具 v1.0" ,
118
+ formatter_class = argparse .RawTextHelpFormatter
119
+ )
120
+
121
+ # 添加命令参数
122
+ parser .add_argument (
123
+ 'operation' ,
124
+ choices = ['to_webp' , 'from_webp' ],
125
+ help = "转换方向:\n "
126
+ " to_webp - 将普通图片转为 WebP\n "
127
+ " from_webp - 将 WebP 转为其他格式"
128
+ )
129
+
130
+ parser .add_argument (
131
+ '-i' , '--input' ,
132
+ default = './input' ,
133
+ help = "输入文件夹路径 (默认: ./input)"
134
+ )
135
+
136
+ parser .add_argument (
137
+ '-o' , '--output' ,
138
+ default = './output' ,
139
+ help = "输出文件夹路径 (默认: ./output)"
140
+ )
141
+
142
+ parser .add_argument (
143
+ '-f' , '--format' ,
144
+ choices = ['jpg' , 'jpeg' , 'png' ],
145
+ default = 'png' ,
146
+ help = "当使用 from_webp 操作时的输出格式 (默认: png)"
147
+ )
148
+
149
+ parser .add_argument (
150
+ '-q' , '--quality' ,
151
+ type = int ,
152
+ choices = range (1 , 101 ),
153
+ default = 85 ,
154
+ metavar = "1-100" ,
155
+ help = "输出图像质量 (默认: 85)"
156
+ )
157
+
158
+ parser .add_argument (
159
+ '-v' , '--version' ,
160
+ action = 'version' ,
161
+ version = '全能图像转换工具 v1.0'
162
+ )
163
+
164
+ # 解析参数
165
+ args = parser .parse_args ()
166
+
167
+ # 执行转换
168
+ try :
169
+ batch_convert (
170
+ args .input ,
171
+ args .output ,
172
+ args .operation ,
173
+ args .format ,
174
+ args .quality
175
+ )
176
+ except KeyboardInterrupt :
177
+ print ("\n 操作已取消" )
178
+ sys .exit (0 )
179
+ except Exception as e :
180
+ print (f"发生错误: { str (e )} " )
181
+ sys .exit (1 )
182
+
183
+
184
+ if __name__ == "__main__" :
185
+ main ()
0 commit comments