批量转灰度图和调整图片大小
import tkinter as tk
from tkinter import filedialog, messagebox, ttk
from PIL import Image, ImageFilter, ImageEnhance
import osclass BatchImageProcessor:def __init__(self, root):self.root = rootself.root.title("图片批量处理器")self.root.geometry("800x600")self.center_window()# 初始化变量self.input_folder = ""self.output_folder = ""self.processing_options = {"resize": False,"resize_width": 800,"resize_height": 600,"grayscale": False,"blur": False,"blur_radius": 2,"contrast": False,"contrast_factor": 1.2,}# 创建界面self.create_widgets()def center_window(self):# 强制更新窗口尺寸信息self.root.update_idletasks()# 获取窗口尺寸window_width = self.root.winfo_width()window_height = self.root.winfo_height()# 计算居中坐标screen_width = self.root.winfo_screenwidth()screen_height = self.root.winfo_screenheight()x = (screen_width - window_width) // 2y = (screen_height - window_height) // 2# 设置窗口位置self.root.geometry(f"+{x}+{y}")def create_widgets(self):# 顶部框架 - 文件夹选择folder_frame = tk.LabelFrame(self.root, text="文件夹设置", padx=10, pady=10)folder_frame.pack(fill="x", padx=10, pady=5)# 输入文件夹tk.Label(folder_frame, text="输入文件夹:").grid(row=0, column=0, sticky="w")self.input_entry = tk.Entry(folder_frame, width=50)self.input_entry.grid(row=0, column=1, padx=5)tk.Button(folder_frame,text="浏览...",command=self.select_input_folder).grid(row=0, column=2)# 输出文件夹tk.Label(folder_frame, text="输出文件夹:").grid(row=1, column=0, sticky="w")self.output_entry = tk.Entry(folder_frame, width=50)self.output_entry.grid(row=1, column=1, padx=5)tk.Button(folder_frame,text="浏览...",command=self.select_output_folder).grid(row=1, column=2)# 中间框架 - 处理选项option_frame = tk.LabelFrame(self.root, text="处理选项", padx=10, pady=10)option_frame.pack(fill="both", expand=True, padx=10, pady=5)# 调整大小选项self.resize_var = tk.BooleanVar()tk.Checkbutton(option_frame,text="调整大小",variable=self.resize_var,command=self.toggle_resize).grid(row=0, column=0, sticky="w")self.resize_width_label = tk.Label(option_frame, text="宽度:")self.resize_width_label.grid(row=0, column=1, sticky="e")self.resize_width_entry = tk.Entry(option_frame, width=5)self.resize_width_entry.grid(row=0, column=2)self.resize_width_entry.insert(0, "800")tk.Label(option_frame, text="高度:").grid(row=0, column=3, sticky="e")self.resize_height_entry = tk.Entry(option_frame, width=5)self.resize_height_entry.grid(row=0, column=4)self.resize_height_entry.insert(0, "600")# 其他选项self.grayscale_var = tk.BooleanVar()tk.Checkbutton(option_frame,text="转为灰度图",variable=self.grayscale_var).grid(row=1, column=0, sticky="w")self.blur_var = tk.BooleanVar()tk.Checkbutton(option_frame,text="模糊效果",variable=self.blur_var,command=self.toggle_blur).grid(row=1, column=1, sticky="w")self.blur_radius_label = tk.Label(option_frame, text="模糊半径:")self.blur_radius_label.grid(row=1, column=2, sticky="e")self.blur_radius_entry = tk.Entry(option_frame, width=5)self.blur_radius_entry.grid(row=1, column=3)self.blur_radius_entry.insert(0, "2")self.contrast_var = tk.BooleanVar()tk.Checkbutton(option_frame,text="调整对比度",variable=self.contrast_var,command=self.toggle_contrast).grid(row=2, column=0, sticky="w")self.contrast_label = tk.Label(option_frame, text="对比度系数:")self.contrast_label.grid(row=2, column=1, sticky="e")self.contrast_entry = tk.Entry(option_frame, width=5)self.contrast_entry.grid(row=2, column=2)self.contrast_entry.insert(0, "1.2")# 底部框架 - 操作按钮和进度条control_frame = tk.Frame(self.root)control_frame.pack(fill="x", padx=10, pady=5)tk.Button(control_frame,text="开始处理",command=self.start_processing,width=15).pack(side="left", padx=5)tk.Button(control_frame,text="退出",command=self.root.quit,width=15).pack(side="right", padx=5)# 进度条self.progress = ttk.Progressbar(self.root,orient="horizontal",length=500,mode="determinate")self.progress.pack(pady=10)self.status_label = tk.Label(self.root, text="准备就绪", bd=1, relief="sunken", anchor="w")self.status_label.pack(fill="x", padx=10, pady=5)# 初始化选项状态self.toggle_resize()self.toggle_blur()self.toggle_contrast()def toggle_resize(self):state = "normal" if self.resize_var.get() else "disabled"self.resize_width_entry.config(state=state)self.resize_height_entry.config(state=state)self.resize_width_label.config(state=state)def toggle_blur(self):state = "normal" if self.blur_var.get() else "disabled"self.blur_radius_entry.config(state=state)self.blur_radius_label.config(state=state)def toggle_contrast(self):state = "normal" if self.contrast_var.get() else "disabled"self.contrast_entry.config(state=state)self.contrast_label.config(state=state)def select_input_folder(self):folder = filedialog.askdirectory(title="选择输入文件夹")if folder:self.input_folder = folderself.input_entry.delete(0, tk.END)self.input_entry.insert(0, folder)def select_output_folder(self):folder = filedialog.askdirectory(title="选择输出文件夹")if folder:self.output_folder = folderself.output_entry.delete(0, tk.END)self.output_entry.insert(0, folder)def update_status(self, message):self.status_label.config(text=message)self.root.update_idletasks()def process_image(self, img_path, output_path):try:with Image.open(img_path) as img:# 调整大小if self.resize_var.get():width = int(self.resize_width_entry.get())height = int(self.resize_height_entry.get())img = img.resize((width, height), Image.Resampling.LANCZOS)# 转为灰度图if self.grayscale_var.get():img = img.convert("L")# 模糊效果if self.blur_var.get():radius = float(self.blur_radius_entry.get())img = img.filter(ImageFilter.GaussianBlur(radius))# 调整对比度if self.contrast_var.get():factor = float(self.contrast_entry.get())enhancer = ImageEnhance.Contrast(img)img = enhancer.enhance(factor)# 保存图片img.save(output_path)return Trueexcept Exception as e:print(f"处理图片 {img_path} 时出错: {e}")return Falsedef start_processing(self):# 验证输入if not self.input_folder or not os.path.isdir(self.input_folder):messagebox.showerror("错误", "请选择有效的输入文件夹")returnif not self.output_folder:messagebox.showerror("错误", "请选择输出文件夹")returnif not os.path.exists(self.output_folder):os.makedirs(self.output_folder)# 获取图片文件列表image_files = [f for f in os.listdir(self.input_folder)if f.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif'))]if not image_files:messagebox.showwarning("警告", "输入文件夹中没有找到图片文件")return# 设置进度条self.progress["maximum"] = len(image_files)self.progress["value"] = 0# 开始处理processed = 0for i, filename in enumerate(image_files, 1):input_path = os.path.join(self.input_folder, filename)output_path = os.path.join(self.output_folder, filename)self.update_status(f"正在处理: {filename} ({i}/{len(image_files)})")if self.process_image(input_path, output_path):processed += 1self.progress["value"] = iself.root.update_idletasks()# 处理完成self.update_status(f"处理完成! 成功处理 {processed}/{len(image_files)} 张图片")messagebox.showinfo("完成", f"批量处理完成!\n成功处理 {processed} 张图片")if __name__ == "__main__":root = tk.Tk()app = BatchImageProcessor(root)root.mainloop()