0

I need to create a widget that acts like Window's snipping tool and saves the cropped image on button release.
It works perfectly fine, except that the image gets cropped and saved as if it was given the wrong coordinates. I have checked a full screen snip and the coordinates are (0,0,1279,719), which is my screen resolution, so I don´t understand why ImageGrab.grab(bbox=) can't crop correctly.
Here is the code.

from PIL import *
from tkinter import *
from PIL import ImageGrab

class Widget(Frame):
    def __init__(self,master):

        Frame.__init__(self,master=None)
        self.root = master
        self.root.attributes("-alpha", 0.2)
        self.root.attributes("-fullscreen", True)
        self.root.title("")

        self.canvas = Canvas(self, cursor="cross", background="blue", width= master.winfo_screenwidth(), height=master.winfo_screenheight() )

        self.canvas.pack()

        self.canvas.bind("<ButtonPress-1>", self.on_button_press)
        self.canvas.bind("<B1-Motion>", self.on_move_press)
        self.canvas.bind("<ButtonRelease-1>", self.on_button_release)

        self.rect = None

        self.start_x = None
        self.start_y = None

    def on_button_press(self, event):
        # save mouse drag start position
        self.start_x = self.canvas.canvasx(event.x)
        self.start_y = self.canvas.canvasy(event.y)

        self.rect = self.canvas.create_rectangle(0, 0, 1, 1, outline='red')

    def on_move_press(self, event):
        curX = self.canvas.canvasx(event.x)
        curY = self.canvas.canvasy(event.y)

        # expand rectangle as you drag the mouse
        self.canvas.coords(self.rect, self.start_x, self.start_y, curX, curY)    

    def on_button_release(self, event):
        self.endx = self.canvas.canvasx(event.x)
        self.endy = self.canvas.canvasy(event.y)

        x1 = min(self.start_x, self.endx)
        y1 = min(self.start_y, self.endy)
        x2 = max(self.start_x, self.endx)
        y2 = max(self.start_y, self.endy)

        self.root.destroy()
        img = ImageGrab.grab(bbox=(x1, y1, x2, y2))
        img.save('capture.png')

if __name__ == "__main__":
    snip_window = Tk()
    width = snip_window.winfo_screenwidth()
    height = snip_window.winfo_screenheight()
    snip_window.geometry(f'{width}x{height}')
    snip_widget = Widget(snip_window)
    snip_widget.pack()
    snip_window.mainloop()
Delrius Euphoria
  • 14,910
  • 3
  • 15
  • 46

0 Answers0