How To Give Dynamic Value For Area Selection In Imagegrab Library In Python
Using this script i am trying to take a screenshot of my desktop of a particular area.(using Tkinter gui) But with this code i can only take screenshot of the fix area (frame) of d
Solution 1:
You can use Pillow
to do what you want:
import tkinter as tk
from PIL import Image, ImageTk, ImageGrab, ImageEnhance
root = tk.Tk()
root.resizable(0, 0)
defshow_image(image):
win = tk.Toplevel()
win.image = ImageTk.PhotoImage(image)
tk.Label(win, image=win.image).pack()
win.grab_set()
win.wait_window(win)
defarea_sel():
x1 = y1 = x2 = y2 = 0
roi_image = Nonedefon_mouse_down(event):
nonlocal x1, y1
x1, y1 = event.x, event.y
canvas.create_rectangle(x1, y1, x1, y1, outline='red', tag='roi')
defon_mouse_move(event):
nonlocal roi_image, x2, y2
x2, y2 = event.x, event.y
canvas.delete('roi-image') # remove old overlay image
roi_image = image.crop((x1, y1, x2, y2)) # get the image of selected region
canvas.image = ImageTk.PhotoImage(roi_image)
canvas.create_image(x1, y1, image=canvas.image, tag=('roi-image'), anchor='nw')
canvas.coords('roi', x1, y1, x2, y2)
# make sure the select rectangle is on top of the overlay image
canvas.lift('roi')
root.withdraw() # hide the root window
image = ImageGrab.grab() # grab the fullscreen as select region background
bgimage = ImageEnhance.Brightness(image).enhance(0.3) # darken the capture image# create a fullscreen window to perform the select region action
win = tk.Toplevel()
win.attributes('-fullscreen', 1)
win.attributes('-topmost', 1)
canvas = tk.Canvas(win, highlightthickness=0)
canvas.pack(fill='both', expand=1)
tkimage = ImageTk.PhotoImage(bgimage)
canvas.create_image(0, 0, image=tkimage, anchor='nw', tag='images')
# bind the mouse events for selecting region
win.bind('<ButtonPress-1>', on_mouse_down)
win.bind('<B1-Motion>', on_mouse_move)
win.bind('<ButtonRelease-1>', lambda e: win.destroy())
# use Esc key to abort the capture
win.bind('<Escape>', lambda e: win.destroy())
# make the capture window modal
win.focus_force()
win.grab_set()
win.wait_window(win)
root.deiconify() # restore root window# show the capture imageif roi_image:
show_image(roi_image)
tk.Button(root, text='select area', width=30, command=area_sel).pack()
root.mainloop()
During selecting region:
Show the capture image after selecting region:
Solution 2:
Use pynput
is a way to do this(Maybe only use tkinter
can do this,but I don't know),You only need to know the position of mouse button pressed and mouse button released:
Read more about pynput module
import tkinter as tk
# from tkinter import *from PIL import Image, ImageGrab,ImageTk
from pynput import mouse
from pynput.keyboard import Key, Listener
defgetPostion():
defon_click(x, y, button, pressed):
global Click_x, Click_y, Release_x, Release_y, STOP
if pressed:
Click_x = x
Click_y = y
else:
Keyboardlistener.stop()
Release_x = x
Release_y = y
STOP = FalsereturnFalsedefon_release(key):
global STOP
if key == Key.esc:
Mouselistener.stop()
STOP = TruereturnFalsewith mouse.Listener(on_click=on_click) as Mouselistener, Listener(on_release=on_release) as Keyboardlistener:
Mouselistener.join()
Keyboardlistener.join()
root = tk.Tk()
defarea_sel():
global Click_x, Click_y, Release_x, Release_y, STOP
Click_x, Click_y, Release_x, Release_y= 0,0,0,0# using the grab method
top = tk.Toplevel() # create a toplevel
top.wm_attributes('-alpha',0.3)
top.state('zoomed') # make window fullscreen
top.overrideredirect(1)
# background = ImageTk.PhotoImage(image=ImageGrab.grab()) # get a screenshot
fullCanvas = tk.Canvas(top) # make a fullscreen canvas# fullCanvas.create_image(xx,xx) # create a screenshot image in this canvas.
fullCanvas.pack()
top.update()
getPostion()
if Click_x and Click_y and Release_x and Release_y:
if STOP:
returnFalse
top.withdraw()
img = ImageGrab.grab(bbox = (Click_x, Click_y, Release_x, Release_y))
img.show()
STOP = False
sel_btn = tk.Button(root, text='select area', width=20, command=area_sel)
sel_btn.pack()
root.mainloop()
edit now it is a complete tool can take a scroonshot,it is needn't to use pynput
full code :
import tkinter as tk
# from tkinter import *from PIL import Image, ImageGrab, ImageTk
import ctypes, sys
if sys.getwindowsversion().major == 10:
ctypes.windll.shcore.SetProcessDpiAwareness(2) # Set DPI awareness
root = tk.Tk()
defarea_sel():
defgetPress(event): # get press positionglobal press_x,press_y
press_x,press_y = event.x,event.y
defmouseMove(event): # movementglobal press_x, press_y, rectangleId
fullCanvas.delete(rectangleId)
rectangleId = fullCanvas.create_rectangle(press_x,press_y,event.x,event.y,width=5)
defgetRelease(event): # get release positionglobal press_x, press_y, rectangleId
top.withdraw()
img = ImageGrab.grab((press_x, press_y,event.x,event.y))
img.show()
top = tk.Toplevel()
top.state('zoomed')
top.overrideredirect(1)
fullCanvas = tk.Canvas(top)
background = ImageTk.PhotoImage(ImageGrab.grab().convert("L"))
fullCanvas.create_image(0,0,anchor="nw",image=background)
# bind event for canvas
fullCanvas.bind('<Button-1>',getPress)
fullCanvas.bind('<B1-Motion>',mouseMove)
fullCanvas.bind('<ButtonRelease-1>',getRelease)
fullCanvas.pack(expand="YES",fill="both")
top.mainloop()
rectangleId = None
sel_btn = tk.Button(root, text='select area', width=20, command=area_sel)
sel_btn.pack()
root.mainloop()
Post a Comment for "How To Give Dynamic Value For Area Selection In Imagegrab Library In Python"