当前位置: 首页 > news >正文

批量转灰度图和调整图片大小

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()

 

http://www.xdnf.cn/news/974773.html

相关文章:

  • 如何在 TypeScript 中使用类型保护
  • Vim鼠标右键复制问题解决方法
  • java转PHP开发需要几步?
  • PHP基础-语法变量
  • LVS 负载均衡详解:四层转发原理与三种经典模式全面解析
  • 谈文件系统
  • Vue 中的数据代理机制
  • 中兴B860AV1.1_MSO9280_降级后开ADB-免刷机破解教程(非刷机)
  • Java面试题019:一文深入了解微服务之负载均衡Ribbon
  • Wireshark 筛选功能详解:语法与示例
  • 一些学习网站分享
  • OctoPrint公网部署如何实现?3D打印远程控制一键部署过程!
  • 《零基础读懂新能源汽车》——V2G/电池梯次利用/氢能源生态级技术拆解与商业预言
  • 智能体商业化:创建-接入-封装成小程序/网站/H5
  • PHP7+MySQL5.6 雪里开简易预约制访客管理系统V1.0
  • 深度解读云防火墙(WAF):守护网络安全的智能卫士
  • 在当系统未连接上wifi的时候,直接不显示wifi列表 ,这个判断导致?
  • UI 设计|审美积累|新拟态风格(Neumorphism)
  • 【华为Pura80系列】鸿蒙生态再升级:Pura 80 系列影像突破,WATCH 5 开启智能手表新纪元
  • 2025 年 MQTT 技术趋势:驱动 AI 与物联网未来发展的关键动力
  • 理解什么是并查集
  • 阿糖胞苷联合伊达比星为代表的强化治疗方案引领AML多阶段治疗新进展
  • 学习threejs,使用TSL计算粒子鼠标特效
  • Maven 构建性能优化深度剖析:原理、策略与实践
  • 目标检测yolo算法
  • AI赋能Automa二次开发
  • 超市售货管理平台小程序
  • 2025年渗透测试面试题总结-长亭科技[实习]安全服务工程师题目+回答)
  • 板凳-------Mysql cookbook学习 (十--5)
  • 仓库物资出入库管理系统源码+uniapp小程序