import os.path import threading import tkinter as tk from tkinter import ttk, filedialog, messagebox from PIL import Image, ImageTk import sv_ttk class ImageApp: def __init__(self, root): self.image_path = None self.image_name = None self.root = root self.root.title("车牌识别") # 主布局为横向分割 self.main_frame = ttk.Frame(root) self.main_frame.pack(fill='both', expand=True) self.left_frame = ttk.Frame(self.main_frame) self.left_frame.pack(side='left', fill='both', expand=True, padx=10, pady=10) self.right_frame = ttk.Frame(self.main_frame) self.right_frame.pack( side='right', fill='both', expand=True, padx=10, pady=10 ) self.open_button = ttk.Button( self.left_frame, text="选择图片", command=self.load_image ) self.open_button.pack(anchor="n") self.origin_label = ttk.Label(self.left_frame, text="Origin Image") self.origin_label.pack(pady=5) self.origin_canvas = tk.Label(self.left_frame, borderwidth=2, relief="ridge") self.origin_canvas.pack(fill='both', expand=True) self.save_button = ttk.Button( self.right_frame, text="保存图片", command=self.save_image ) self.save_button.pack(anchor="n") self.handle_label = ttk.Label(self.right_frame, text="Handle Image") self.handle_label.pack(pady=5) # ["raised", "sunken", "flat", "ridge", "solid", "groove"] self.handle_canvas = tk.Label(self.right_frame, borderwidth=2, relief="groove") self.handle_canvas.pack(fill='both', expand=True) self.origin_img = None self.handled_img = None self.tk_origin = None self.tk_handled = None def load_image(self): path = filedialog.askopenfilename( filetypes=[("Image files", "*.jpg *.png *.jpeg *.bmp *.gif")] ) if path: self.origin_img = Image.open(path) width ,height = self.origin_canvas.winfo_width(), self.origin_canvas.winfo_height() print(width,height) self.tk_origin = ImageTk.PhotoImage(self.origin_img.resize((width , height))) self.origin_canvas.config(image=self.tk_origin) self.image_name = path.split("/")[-1] self.image_path = path threading.Thread(target=self.process_image, daemon=True).start() def handle_image(self): self.handled_img = self.origin_img.convert("L") width, height = ( self.origin_canvas.winfo_width(), self.origin_canvas.winfo_height(), ) self.tk_handled = ImageTk.PhotoImage(self.handled_img.resize((width , height ))) self.handle_canvas.config(image=self.tk_handled) def process_image(self): # 耗时操作在线程中执行 from detect_plate import start self.handle_label.config(text="Handle Image (正在识别中...)") start(self.image_path) cwd = os.getcwd() recognize_result_path = os.path.join("result", self.image_name) recognize_result_path = cwd + "\\" + recognize_result_path print(recognize_result_path) # 回到主线程更新 UI(Tkinter 所有 UI 更新必须在主线程) def update_ui(): result = Image.open(recognize_result_path) self.handled_img = result width, height = ( self.origin_canvas.winfo_width(), self.origin_canvas.winfo_height(), ) self.tk_handled = ImageTk.PhotoImage(self.handled_img.resize((width, height))) self.handle_canvas.config(image=self.tk_handled) self.handle_label.config(text="Handle Image") self.root.after(0, update_ui) def save_image(self): if self.handled_img: save_path = filedialog.asksaveasfilename( title="保存图像", initialdir=os.path.expanduser("~/Downloads"), initialfile=self.image_name, defaultextension=".png", filetypes=[("PNG files", "*.png"), ("All files", "*.*")], ) if save_path: self.handled_img.save(save_path) messagebox.showinfo("保存成功", f"图像已保存到:{save_path}") else: messagebox.showwarning("未处理图像", "请先选择图像再保存。") def center_window(win, width, height): screen_width = win.winfo_screenwidth() screen_height = win.winfo_screenheight() x = (screen_width - width) // 2 y = (screen_height - height) // 2 win.geometry(f"{width}x{height}+{x}+{y}") if __name__ == "__main__": root = tk.Tk() app = ImageApp(root) sv_ttk.set_theme("dark") center_window(root, 1600, 800 ) root.mainloop()