-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcropper.py
More file actions
112 lines (85 loc) · 3.71 KB
/
cropper.py
File metadata and controls
112 lines (85 loc) · 3.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import tkinter as tk
from tkinter import filedialog
from PIL import Image, ImageTk
import os
class ImageCropper:
def __init__(self, master):
self.master = master
self.image_path = ''
self.image = None
self.tk_image = None
self.rect_id = None
self.start_x = 0
self.start_y = 0
self.end_x = 0
self.end_y = 0
self.canvas = tk.Canvas(master, width=800, height=600)
self.canvas.pack()
button_frame = tk.Frame(master)
button_frame.pack(side=tk.BOTTOM, fill=tk.X)
open_button = tk.Button(button_frame, text='Open Image', command=self.open_image)
open_button.pack(side=tk.LEFT)
crop_button = tk.Button(button_frame, text='Crop Image', command=self.crop_image)
crop_button.pack(side=tk.LEFT)
save_button = tk.Button(button_frame, text='Save Image', command=self.save_image)
save_button.pack(side=tk.LEFT)
self.canvas.bind("<ButtonPress-1>", self.on_button_press)
self.canvas.bind("<B1-Motion>", self.on_button_move)
aspect_ratio_button = tk.Button(button_frame, text='Set Aspect Ratio', command=self.set_aspect_ratio)
aspect_ratio_button.pack(side=tk.LEFT)
# Add a variable to hold the aspect ratio
self.aspect_ratio = None
def open_image(self):
self.image_path = filedialog.askopenfilename()
self.image = Image.open(self.image_path)
self.display_image()
def display_image(self):
max_size = (800, 800)
self.image.thumbnail(max_size)
self.tk_image = ImageTk.PhotoImage(self.image)
self.canvas.create_image(0, 0, anchor='nw', image=self.tk_image)
def on_button_press(self, event):
self.start_x = event.x
self.start_y = event.y
if self.rect_id is not None:
self.canvas.delete(self.rect_id)
self.rect_id = self.canvas.create_rectangle(self.start_x, self.start_y, self.start_x, self.start_y, outline='red')
def on_button_move(self, event):
self.end_x = event.x
# Compute new rectangle height based on the aspect ratio
if self.aspect_ratio:
rect_height = abs(self.end_x - self.start_x) / self.aspect_ratio
else:
rect_height = 0.75 * abs(self.end_x - self.start_x) # Existing behavior
self.end_y = self.start_y + rect_height
self.canvas.coords(self.rect_id, self.start_x, self.start_y, self.end_x, self.end_y)
def crop_image(self):
if self.rect_id is not None:
bbox = self.canvas.coords(self.rect_id)
if len(bbox) == 4:
x1, y1, x2, y2 = map(int, bbox)
if x1 < x2 and y1 < y2:
self.image = self.image.crop((x1, y1, x2, y2))
self.display_image()
def save_image(self):
if self.image is not None:
base_name, ext = os.path.splitext(self.image_path)
directory = os.path.dirname(base_name)
cropped_directory = os.path.join(directory, 'Cropped')
if not os.path.exists(cropped_directory):
os.makedirs(cropped_directory)
new_base_name = os.path.basename(base_name)
new_image_path = os.path.join(cropped_directory, f"{new_base_name}_cropped{ext}")
self.image.save(new_image_path)
def set_aspect_ratio(self):
# Open a new image
new_image_path = filedialog.askopenfilename()
if new_image_path:
new_image = Image.open(new_image_path)
# Compute the aspect ratio
width, height = new_image.size
self.aspect_ratio = width / height
if __name__ == "__main__":
root = tk.Tk()
ImageCropper(root)
root.mainloop()