84 lines
3.1 KiB
Python
84 lines
3.1 KiB
Python
|
import tkinter as tk
|
||
|
from tkinter import filedialog, messagebox
|
||
|
from PIL import Image, ImageTk, ImageGrab
|
||
|
|
||
|
class ImageCropApp:
|
||
|
def __init__(self, root):
|
||
|
self.root = root
|
||
|
self.root.title("Image Crop Tool")
|
||
|
|
||
|
# 选择图片按钮
|
||
|
self.select_button = tk.Button(root, text="选择图片", command=self.select_image)
|
||
|
self.select_button.pack(pady=10)
|
||
|
|
||
|
# 画布,用于显示图片
|
||
|
self.canvas = tk.Canvas(root, cursor="cross")
|
||
|
self.canvas.pack(fill=tk.BOTH, expand=True)
|
||
|
|
||
|
self.image = None # 用于保存选择的图片
|
||
|
self.rect_start_x = 0
|
||
|
self.rect_start_y = 0
|
||
|
self.rect_end_x = 0
|
||
|
self.rect_end_y = 0
|
||
|
self.rect = None
|
||
|
self.tk_image = None
|
||
|
|
||
|
# 鼠标事件
|
||
|
self.canvas.bind("<Button-1>", self.start_selection)
|
||
|
self.canvas.bind("<B1-Motion>", self.update_selection)
|
||
|
self.canvas.bind("<ButtonRelease-1>", self.finish_selection)
|
||
|
|
||
|
def select_image(self):
|
||
|
image_path = filedialog.askopenfilename(title="选择图片", filetypes=[("Image files", "*.jpg;*.png;*.jpeg;*.bmp"), ("All files", "*.*")])
|
||
|
if image_path:
|
||
|
self.image = Image.open(image_path)
|
||
|
self.display_image()
|
||
|
|
||
|
def display_image(self):
|
||
|
# 调整图片大小适应窗口
|
||
|
self.image.thumbnail((self.root.winfo_width(), self.root.winfo_height()))
|
||
|
self.tk_image = ImageTk.PhotoImage(self.image)
|
||
|
self.canvas.create_image(0, 0, anchor="nw", image=self.tk_image)
|
||
|
|
||
|
def start_selection(self, event):
|
||
|
# 记录起始点
|
||
|
self.rect_start_x = event.x
|
||
|
self.rect_start_y = event.y
|
||
|
# 创建一个选择框
|
||
|
self.rect = self.canvas.create_rectangle(self.rect_start_x, self.rect_start_y, self.rect_start_x, self.rect_start_y, outline="red", width=2)
|
||
|
|
||
|
def update_selection(self, event):
|
||
|
# 更新选择框大小
|
||
|
self.rect_end_x = event.x
|
||
|
self.rect_end_y = event.y
|
||
|
self.canvas.coords(self.rect, self.rect_start_x, self.rect_start_y, self.rect_end_x, self.rect_end_y)
|
||
|
|
||
|
def finish_selection(self, event):
|
||
|
self.rect_end_x = event.x
|
||
|
self.rect_end_y = event.y
|
||
|
self.crop_image()
|
||
|
|
||
|
def crop_image(self):
|
||
|
if self.image:
|
||
|
# 获取选择框的坐标
|
||
|
left = min(self.rect_start_x, self.rect_end_x)
|
||
|
top = min(self.rect_start_y, self.rect_end_y)
|
||
|
right = max(self.rect_start_x, self.rect_end_x)
|
||
|
bottom = max(self.rect_start_y, self.rect_end_y)
|
||
|
|
||
|
# 根据选择框坐标进行裁剪
|
||
|
cropped_image = self.image.crop((left, top, right, bottom))
|
||
|
|
||
|
# 让用户选择保存路径
|
||
|
save_path = filedialog.asksaveasfilename(defaultextension=".png", filetypes=[("PNG files", "*.png"), ("All files", "*.*")])
|
||
|
if save_path:
|
||
|
cropped_image.save(save_path)
|
||
|
messagebox.showinfo("成功", f"图片已保存到: {save_path}")
|
||
|
|
||
|
# 启动 GUI 应用
|
||
|
if __name__ == "__main__":
|
||
|
root = tk.Tk()
|
||
|
app = ImageCropApp(root)
|
||
|
root.geometry("800x600") # 设置初始窗口大小
|
||
|
root.mainloop()
|