Skip to content Skip to sidebar Skip to footer

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:

enter image description here

Show the capture image after selecting region:

enter image description here

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"