如何使用Python使用像截图工具这样的单击和拖动方法来截取屏幕截图?

Jul*_*ian 3 python screenshot selection

我正在编写一个基本上是截图工具的Python 程序。我希望能够运行我的程序,使用鼠标单击并拖动选择屏幕截图区域,然后让程序保存该图像。

我正在尝试使用此处找到的代码:http ://pyscreenshot.readthedocs.io/en/latest/

#-- include('examples/showgrabfullscreen.py') --#
import pyscreenshot as ImageGrab

if __name__ == '__main__':

# grab fullscreen
im = ImageGrab.grab()

# save image file
im.save('screenshot.png')

# show image in a window
im.show()
#-#
Run Code Online (Sandbox Code Playgroud)

(在“抓取并显示屏幕的一部分”下),但这不允许用户单击并拖动。有谁知道我该怎么做?我在网上找到了一些示例,但它们都有数百行长,我认为这个简单的程序不应该那么长(但我可能是错的)。

谢谢!

Bre*_*rre 5

我通过在透明图层上绘图解决了这个问题。这将允许用户看穿不可见的绘图层并提供用于绘制剪切框的表面。当用户释放剪切框功能时,它将破坏不可见层并捕获框坐标。然后,它将在捕获的坐标内拍摄屏幕截图,并创建并保存此带时间戳的图像到名为“snips”的目录(随意调整)。

from tkinter import *
import pyautogui

import datetime


def take_bounded_screenshot(x1, y1, x2, y2):
    image = pyautogui.screenshot(region=(x1, y1, x2, y2))
    file_name = datetime.datetime.now().strftime("%f")
    image.save("snips/" + file_name + ".png")


class Application():
    def __init__(self, master):
        self.snip_surface = None
        self.master = master
        self.start_x = None
        self.start_y = None
        self.current_x = None
        self.current_y = None

        root.geometry('400x50+200+200')  # set new geometry
        root.title('Lil Snippy')

        self.menu_frame = Frame(master)
        self.menu_frame.pack(fill=BOTH, expand=YES, padx=1, pady=1)

        self.buttonBar = Frame(self.menu_frame, bg="")
        self.buttonBar.pack()

        self.snipButton = Button(self.buttonBar, width=5, height=5, command=self.create_screen_canvas, background="green")
        self.snipButton.pack()

        self.master_screen = Toplevel(root)
        self.master_screen.withdraw()
        self.master_screen.attributes("-transparent", "maroon3")
        self.picture_frame = Frame(self.master_screen, background="maroon3")
        self.picture_frame.pack(fill=BOTH, expand=YES)

    def create_screen_canvas(self):
        self.master_screen.deiconify()
        root.withdraw()

        self.snip_surface = Canvas(self.picture_frame, cursor="cross", bg="grey11")
        self.snip_surface.pack(fill=BOTH, expand=YES)

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

        self.master_screen.attributes('-fullscreen', True)
        self.master_screen.attributes('-alpha', .3)
        self.master_screen.lift()
        self.master_screen.attributes("-topmost", True)

    def on_button_release(self, event):
        self.display_rectangle_position()

        if self.start_x <= self.current_x and self.start_y <= self.current_y:
            print("right down")
            take_bounded_screenshot(self.start_x, self.start_y, self.current_x - self.start_x, self.current_y - self.start_y)

        elif self.start_x >= self.current_x and self.start_y <= self.current_y:
            print("left down")
            take_bounded_screenshot(self.current_x, self.start_y, self.start_x - self.current_x, self.current_y - self.start_y)

        elif self.start_x <= self.current_x and self.start_y >= self.current_y:
            print("right up")
            take_bounded_screenshot(self.start_x, self.current_y, self.current_x - self.start_x, self.start_y - self.current_y)

        elif self.start_x >= self.current_x and self.start_y >= self.current_y:
            print("left up")
            take_bounded_screenshot(self.current_x, self.current_y, self.start_x - self.current_x, self.start_y - self.current_y)

        self.exit_screenshot_mode()
        return event

    def exit_screenshot_mode(self):
        self.snip_surface.destroy()
        self.master_screen.withdraw()
        root.deiconify()

    def on_button_press(self, event):
        # save mouse drag start position
        self.start_x = self.snip_surface.canvasx(event.x)
        self.start_y = self.snip_surface.canvasy(event.y)
        self.snip_surface.create_rectangle(0, 0, 1, 1, outline='red', width=3, fill="maroon3")

    def on_snip_drag(self, event):
        self.current_x, self.current_y = (event.x, event.y)
        # expand rectangle as you drag the mouse
        self.snip_surface.coords(1, self.start_x, self.start_y, self.current_x, self.current_y)

    def display_rectangle_position(self):
        print(self.start_x)
        print(self.start_y)
        print(self.current_x)
        print(self.current_y)


if __name__ == '__main__':
    root = Tk()
    app = Application(root)
    root.mainloop()
Run Code Online (Sandbox Code Playgroud)

  • 我尝试了这个,但它显然只适用于一台显示器:“pyautogui”尚不支持多个显示器。还有其他方法吗?? (2认同)