如何在 MacOS 上捕获 tkinter window 的图像(屏幕截图)

How to capture image (screenshot) of tkinter window on MacOS

我在 Python tkinter 中创建了一个 GUI 应用程序,用于在我的实验室中分析数据。有许多按钮、数字和 canvas 小部件。仅使用一个适当保存文件名的按钮截取整个 window ('root') 的屏幕截图会很有帮助。使用 Mac 的内置“屏幕截图”应用程序的示例 here.

相关问题 , here, and here, but none worked successfully. The final link 基本成功了,但是保存的图片是我电脑的桌面背景。我的电脑是 Mac, MacOS Monterey 12.0.1.

'root' 是 tkinter window 因为

root = tk.Tk()

出现在脚本的开头,类似于示例here中的'window'。我在下面的代码示例中使用 PIL.ImageGrab

这是当前代码,它对我的​​桌面背景进行了无用的截图,

def screenshot():
    # retrieve the time string to use as a filename
    file_name = root.time_string[-6:]
    full_file_name = file_name + '_summary' + '.png'
    x = root.winfo_rootx() + root.winfo_x()
    y = root.winfo_rooty() + root.winfo_y()
    x1 = x + root.winfo_width()
    y1 = y + root.winfo_height()
    ImageGrab.grab().crop((x, y, x1, y1)).save(full_file_name)

我是这样创建按钮的:

screenshot_btn = tk.Button(root, text='Screenshot', command=lambda: screenshot(), font=('Verdana', 24), state=DISABLED)

然后我将按钮放在 'root' 中,如下所示:

screenshot_btn.grid(row=11, column=3)

[这是我在 Whosebug 上的第一个 post。如果我在第一次尝试时没有完全遵循所有指南,我提前道歉。感谢您的耐心等待。]

首先,抓取显示我的桌面没有问题,但它显示的图像裁剪不当。

我找到了一个 hacky 解决方案。问题似乎与决议有关。所以尺寸需要一些缩放。

我所做的是从 ImageGrab.grab().save(full_file_name) 获取输出(无裁剪)并测量所需图像区域的大小(以像素为单位)。这些维度将称为 x_pixelsy_pixels

然后我以屏幕单位测量了实际 window 上的相同区域。我通过调出显示区域尺寸的 mac 屏幕截图工具来做到这一点。然后我将这些维度称为 x_screeny_screen。然后我修改了你的截图功能如下

def screenshot():
    # retrieve the time string to use as a filename
    file_name = root.time_string[-6:]
    full_file_name = file_name + '_summary' + '.png'
    x = root.winfo_rootx()
    y = root.winfo_rooty()
    x1 = x + root.winfo_width()
    y1 = y + root.winfo_height()
    x_pixels = 337
    y_pixels = 79
    x_screen = 171
    y_screen = 41
    x = x*(x_pixels/x_screen)
    y = y*(y_pixels/y_screen)
    x1 = x1*(x_pixels/x_screen)
    y1 = y1*(y_pixels/y_screen)
    ImageGrab.grab().crop((x, y, x1, y1)).save(full_file_name)

注意我还删除了 +root.winfo_x()+root.winfo_y()

结果如下图。它并不完美,但我相信如果我更仔细地测量屏幕截图边界处的像素,window 缩放比例会得到改善。

你碰巧有一个“Retina”显示器吗? ImageGrab 没有考虑它从 Mac 的 screencapture 命令收集的 144 DPI 图像。您可以通过将所有 x、y、x1、y1 值乘以 2 来对此进行补偿(但如果您需要考虑 Mac window 标题栏,您可能仍然会遗漏一点)。

或者,使用 pyscreenshot 包(或窃取其代码...)。它使用 screencapture 的“-R”选项来获取图像的正确边界。适用于像我这样的扩展显示器,其中 x co-ord < 0(因为它位于主显示器的左侧)。