1+ import tkinter as tk
2+ from PIL import ImageTk , Image , ImageFilter , ImageDraw
3+
4+ USAGE = """USAGE: Mousewheel Up = Blur+
5+ USAGE: Mousewheel Down = Blur-
6+ USAGE: Mousebutton Left = Create Rectangle (Drag)
7+ USAGE: Mousebutton Right = Delete Rectangle (Click)
8+ USAGE: Enter = Confirm and Exchange"""
9+
10+ class Editor (tk .Canvas ):
11+ def __init__ (self , master , filename , ** kwargs ):
12+ print (USAGE )
13+ self .successful = False
14+ self .master = master
15+ self .rects = {}
16+ self .current_rect = - 1
17+ self .blur = 0.0
18+ self .image = Image .open (filename )
19+ self .blurred = self .image .copy ()
20+ self .image_gui = ImageTk .PhotoImage (self .blurred )
21+ kwargs ["width" ] = self .image_gui .width ()
22+ kwargs ["height" ] = self .image_gui .height ()
23+ super ().__init__ (master , ** kwargs )
24+ self .image_id = self .create_image (0 , 0 , image = self .image_gui , anchor = "nw" )
25+ self .bind ("<MouseWheel>" , self .change_blur )
26+ self .bind ("<Button-1>" , self .new_rect )
27+ self .bind ("<B1-Motion>" , self .resize_rect )
28+ self .bind ("<ButtonRelease-1>" , self .create_rect )
29+ self .bind ("<Return>" , self .finish )
30+ self .focus_force ()
31+
32+ def change_blur (self , event ):
33+ self .blur += 0.5 * (event .delta / 120 )
34+ self .blur = max (0.0 , self .blur )
35+ tmp = self .blurred
36+ self .blurred = self .image .filter (ImageFilter .GaussianBlur (self .blur ))
37+ tmp .close ()
38+ self .image_gui = ImageTk .PhotoImage (self .blurred )
39+ self .itemconfigure (self .image_id , image = self .image_gui )
40+
41+ def new_rect (self , event ):
42+ coords = [event .x , event .y , event .x , event .y ]
43+ self .current_rect = self .create_rectangle (* coords )
44+ self .rects [self .current_rect ] = coords
45+
46+
47+ def resize_rect (self , event ):
48+ self .rects [self .current_rect ][2 ] = event .x
49+ self .rects [self .current_rect ][3 ] = event .y
50+ self .coords (self .current_rect , * self .rects [self .current_rect ])
51+
52+ def create_rect (self , _ ):
53+ def make_deleter (handle ):
54+ return lambda _ : self .delete_rect (handle )
55+ self .itemconfigure (self .current_rect , fill = "BLACK" )
56+ self .tag_bind (self .current_rect , "<Button-3>" , make_deleter (self .current_rect ))
57+
58+ def delete_rect (self , rect ):
59+ self .delete (rect )
60+ del self .rects [rect ]
61+
62+ def finish (self , _ ):
63+ print ("STATUS: Image locked and sent" )
64+ self .successful = True
65+ self .master .quit ()
66+
67+ def cleanup (self ):
68+ self .image .close ()
69+ self .blurred .close ()
70+
71+ def is_successful (self ):
72+ return self .successful
73+
74+ def get_results (self ):
75+ imgs_with_rects = [self .blurred , self .image .copy ()]
76+ for img in imgs_with_rects :
77+ for rect in self .rects .values ():
78+ draw = ImageDraw .Draw (img )
79+ draw .rectangle (rect , "BLACK" , "BLACK" )
80+ return imgs_with_rects [0 ], imgs_with_rects [1 ], self .image
81+
82+ if __name__ == "__main__" :
83+ window = tk .Tk ()
84+ editor = Editor (window , "test.png" )
85+ editor .pack ()
86+ window .mainloop ()
0 commit comments