I have a tool to capture screenshots but this tool only captures screenshots when you hold button-1 and move to the right side, when you hold button-1 and move it to the left side or up, it does not capture the screenshot, what is the reason and how can I fix it? I thought about it, but I think it’s a mathematical problem, I’m waiting for your help.
JavaScript
x
69
69
1
import tkinter as tk
2
from PIL import Image, ImageTk, ImageGrab, ImageEnhance
3
4
root = tk.Tk()
5
root.resizable(0, 0)
6
7
def show_image(image):
8
win = tk.Toplevel()
9
win.image = ImageTk.PhotoImage(image)
10
tk.Label(win, image=win.image).pack()
11
win.grab_set()
12
win.wait_window(win)
13
14
def area_sel():
15
x1 = y1 = x2 = y2 = 0
16
roi_image = None
17
18
def on_mouse_down(event):
19
nonlocal x1, y1
20
x1, y1 = event.x, event.y
21
canvas.create_rectangle(x1, y1, x1, y1, outline='red', tag='roi')
22
23
def button_release(event):
24
print("ok")
25
26
win.destroy()
27
def on_mouse_move(event):
28
nonlocal roi_image, x2, y2
29
x2, y2 = event.x, event.y
30
canvas.delete('roi-image') # remove old overlay image
31
canvas.update()
32
33
roi_image = image.crop((x1, y1, x2, y2)) # get the image of selected region
34
canvas.image = ImageTk.PhotoImage(roi_image)
35
canvas.create_image(x1, y1, image=canvas.image, tag=('roi-image'), anchor='nw')
36
canvas.coords('roi', x1, y1, x2, y2)
37
# make sure the select rectangle is on top of the overlay image
38
canvas.lift('roi')
39
40
root.withdraw() # hide the root window
41
image = ImageGrab.grab() # grab the fullscreen as select region background
42
bgimage = ImageEnhance.Brightness(image).enhance(0.3) # darken the capture image
43
# create a fullscreen window to perform the select region action
44
win = tk.Toplevel()
45
win.attributes('-fullscreen', 1)
46
win.attributes('-topmost', 1)
47
canvas = tk.Canvas(win, highlightthickness=0)
48
canvas.pack(fill='both', expand=1)
49
tkimage = ImageTk.PhotoImage(bgimage)
50
canvas.create_image(0, 0, image=tkimage, anchor='nw', tag='images')
51
# bind the mouse events for selecting region
52
win.bind('<ButtonPress-1>', on_mouse_down)
53
win.bind('<ButtonRelease>', button_release)
54
win.bind('<B1-Motion>', on_mouse_move)
55
# use Esc key to abort the capture
56
win.bind('<Escape>', lambda e: win.destroy())
57
# make the capture window modal
58
win.focus_force()
59
win.grab_set()
60
win.wait_window(win)
61
root.deiconify() # restore root window
62
# show the capture image
63
if roi_image:
64
show_image(roi_image)
65
66
tk.Button(root, text='select area', width=30, command=area_sel).pack()
67
68
root.mainloop()
69
Advertisement
Answer
You need to keep x1
<= x2
and y1 <= y2
when cropping image and creating the roi rectangle:
JavaScript
1
20
20
1
def normalize(x1, y1, x2, y2):
2
if x1 > x2:
3
x1, x2 = x2, x1
4
if y1 > y2:
5
y1, y2 = y2, y1
6
return x1, y1, x2, y2
7
8
def on_mouse_move(event):
9
nonlocal roi_image, x2, y2
10
x2, y2 = event.x, event.y
11
rect = normalize(x1, y1, x2, y2)
12
13
canvas.delete('roi-image') # remove old overlay image
14
roi_image = image.crop(rect) # get the image of selected region
15
canvas.image = ImageTk.PhotoImage(roi_image)
16
canvas.create_image(rect[:2], image=canvas.image, tag=('roi-image'), anchor='nw')
17
canvas.coords('roi', rect)
18
# make sure the select rectangle is on top of the overlay image
19
canvas.lift('roi')
20