[Python] 纯文本查看 复制代码
import os
import tkinter as tk
from tkinter import ttk, filedialog
from tkinterdnd2 import TkinterDnD, DND_FILES
from PIL import Image
import pillow_avif # 处理avif文件
class ImageConverterApp:
def __init__(self, root):
self.root = root
self.root.title("图片批量转换工具 (AVIF/WEBP/PNG/JFIF → JPG)")
self.root.geometry("600x300")
# 创建UI元素
self.create_widgets()
def create_widgets(self):
# 拖拽区域
self.drop_frame = ttk.LabelFrame(self.root, text="拖拽文件到这里", width=550, height=150)
self.drop_frame.pack(pady=20, padx=20, fill=tk.BOTH)
self.drop_frame.pack_propagate(False)
self.drop_label = ttk.Label(self.drop_frame, text="拖拽图片文件或文件夹到这里", font=('Arial', 12))
self.drop_label.pack(expand=True)
# 注册拖拽功能
self.drop_frame.drop_target_register(DND_FILES)
self.drop_frame.dnd_bind('<<Drop>>', self.on_drop)
# 按钮区域
self.button_frame = ttk.Frame(self.root)
self.button_frame.pack(pady=10)
self.select_files_btn = ttk.Button(self.button_frame, text="选择文件", command=self.select_files)
self.select_files_btn.pack(side=tk.LEFT, padx=5)
self.select_folder_btn = ttk.Button(self.button_frame, text="选择文件夹", command=self.select_folder)
self.select_folder_btn.pack(side=tk.LEFT, padx=5)
self.convert_btn = ttk.Button(self.button_frame, text="开始转换", command=self.start_conversion)
self.convert_btn.pack(side=tk.LEFT, padx=5)
# 进度条
self.progress = ttk.Progressbar(self.root, orient=tk.HORIZONTAL, length=500, mode='determinate')
self.progress.pack(pady=10)
# 存储文件路径
self.file_paths = []
def on_drop(self, event):
# 处理拖拽事件
self.file_paths = []
paths = event.data.split() if isinstance(event.data, str) else event.data
for path in paths:
path = path.strip('{}') # 处理Windows路径中的花括号
if os.path.isdir(path):
self.collect_images_from_folder(path)
elif self.is_supported_image(path):
self.file_paths.append(path)
self.update_file_count()
def select_files(self):
# 选择文件对话框
filetypes = (
("图片文件", "*.avif;*.webp;*.png;*.jfif"),
("所有文件", "*.*")
)
files = filedialog.askopenfilenames(title="选择要转换的图片", filetypes=filetypes)
if files:
self.file_paths = [f for f in files if self.is_supported_image(f)]
self.update_file_count()
def select_folder(self):
# 选择文件夹对话框
folder = filedialog.askdirectory(title="选择包含图片的文件夹")
if folder:
self.file_paths = []
self.collect_images_from_folder(folder)
self.update_file_count()
def collect_images_from_folder(self, folder):
# 从文件夹收集支持的图片文件
supported_extensions = ('.avif', '.webp', '.png', '.jfif')
for root, _, files in os.walk(folder):
for file in files:
if file.lower().endswith(supported_extensions):
self.file_paths.append(os.path.join(root, file))
def is_supported_image(self, file_path):
# 检查文件是否是支持的图片格式
ext = os.path.splitext(file_path)[1].lower()
return ext in ('.avif', '.webp', '.png', '.jfif')
def update_file_count(self):
# 更新UI显示文件数量
count = len(self.file_paths)
self.drop_label.config(text=f"已选择 {count} 个文件")
def start_conversion(self):
# 开始转换过程
if not self.file_paths:
return
total_files = len(self.file_paths)
self.progress['maximum'] = total_files
self.progress['value'] = 0
for i, file_path in enumerate(self.file_paths, 1):
try:
# 转换图片
output_path = os.path.splitext(file_path)[0] + '.jpg'
with Image.open(file_path) as img:
if img.mode != 'RGB':
img = img.convert('RGB')
img.save(output_path, 'JPEG', quality=95)
# 删除原文件
os.remove(file_path)
except Exception as e:
pass
self.progress['value'] = i
self.root.update()
# 重置状态
self.file_paths = []
self.update_file_count()
self.progress['value'] = 0
if __name__ == "__main__":
root = TkinterDnD.Tk()
app = ImageConverterApp(root)
root.mainloop()