在Mac OS X上用Python截图

在Mac OS X上用Python截图,python,macos,screenshot,Python,Macos,Screenshot,从PIL获取图像将是理想的选择。我正在寻找类似的功能,特别是定义屏幕截图边界框的功能。我一直在寻找一个可以在MacOSX上使用的库,但没有任何运气。我也找不到任何示例代码(可能是pyobjc?)。虽然不是您想要的,但在必要的情况下,您可以使用: os.system("screencapture screen.png") 然后用图像模块打开该图像。不过,我相信还有更好的解决方案。以下是如何使用PyObjC捕获和保存基于 您可以捕获整个屏幕,或指定要捕获的区域。如果您不需要这样做,我建议只调用sc

从PIL获取图像将是理想的选择。我正在寻找类似的功能,特别是定义屏幕截图边界框的功能。我一直在寻找一个可以在MacOSX上使用的库,但没有任何运气。我也找不到任何示例代码(可能是pyobjc?)。

虽然不是您想要的,但在必要的情况下,您可以使用:

os.system("screencapture screen.png")

然后用图像模块打开该图像。不过,我相信还有更好的解决方案。

以下是如何使用PyObjC捕获和保存基于

您可以捕获整个屏幕,或指定要捕获的区域。如果您不需要这样做,我建议只调用
screenscapture
命令(更多功能、更健壮、更快-仅初始PyObjC导入就需要大约一秒钟)


虽然我知道这条线现在已经快五年了,但我回答这个问题是希望它能帮助人们未来

以下是根据本帖中的答案对我有效的方法(归功于):

安装:

easy_install pyscreenshot
例如:

import pyscreenshot

# fullscreen
screenshot=pyscreenshot.grab()
screenshot.show()

# part of the screen
screenshot=pyscreenshot.grab(bbox=(10,10,500,500))
screenshot.show()

# save to file
pyscreenshot.grab_to_file('screenshot.png')
我发现使用OSX是我最方便的解决方案

brew install webkit2png
webkit2png http://stackoverflow.com
此后,枕头增加了对macOS的支持

但是它不在v2.9中(现在是最新版本),所以我只是将这个文件添加到我的本地模块中

代码如下:

#
# The Python Imaging Library
# $Id$
#
# screen grabber (macOS and Windows only)
#
# History:
# 2001-04-26 fl  created
# 2001-09-17 fl  use builtin driver, if present
# 2002-11-19 fl  added grabclipboard support
#
# Copyright (c) 2001-2002 by Secret Labs AB
# Copyright (c) 2001-2002 by Fredrik Lundh
#
# See the README file for information on usage and redistribution.
#

from . import Image

import sys
if sys.platform not in ["win32", "darwin"]:
    raise ImportError("ImageGrab is macOS and Windows only")

if sys.platform == "win32":
    grabber = Image.core.grabscreen
elif sys.platform == "darwin":
    import os
    import tempfile
    import subprocess


def grab(bbox=None):
    if sys.platform == "darwin":
        fh, filepath = tempfile.mkstemp('.png')
        os.close(fh)
        subprocess.call(['screencapture', '-x', filepath])
        im = Image.open(filepath)
        im.load()
        os.unlink(filepath)
    else:
        size, data = grabber()
        im = Image.frombytes(
            "RGB", size, data,
            # RGB, 32-bit line padding, origin lower left corner
            "raw", "BGR", (size[0]*3 + 3) & -4, -1
            )
    if bbox:
        im = im.crop(bbox)
    return im


def grabclipboard():
    if sys.platform == "darwin":
        fh, filepath = tempfile.mkstemp('.jpg')
        os.close(fh)
        commands = [
            "set theFile to (open for access POSIX file \""+filepath+"\" with write permission)",
            "try",
                "write (the clipboard as JPEG picture) to theFile",
            "end try",
            "close access theFile"
        ]
        script = ["osascript"]
        for command in commands:
            script += ["-e", command]
        subprocess.call(script)

        im = None
        if os.stat(filepath).st_size != 0:
            im = Image.open(filepath)
            im.load()
        os.unlink(filepath)
        return im
    else:
        debug = 0  # temporary interface
        data = Image.core.grabclipboard(debug)
        if isinstance(data, bytes):
            from . import BmpImagePlugin
            import io
            return BmpImagePlugin.DibImageFile(io.BytesIO(data))
        return data

CTRL+Shift+3

CTRL+Shift+4


在mac中获取屏幕截图

虽然有点明显忘记提到它,但我没有使用ImageGrab,因为它只在Windows上工作。ImageGrab现在也在mac上工作。如果没有更好的东西出现,我想那就只好这样了;)我想没有比这更好的了,所以我接受你的答案。比大多数人快0.3秒。遗憾的是,没有办法降低质量,所以屏幕截图工作得更快:PThis实际上非常好,因为它实现了高级别的代码重用<代码>截屏已经解决了很多棘手的问题。:-)从CGWindowListCreateImage获取图像后,您是否知道是否有办法直接将其作为SimpleCV图像加载(而不是将图像保存到文件中,然后从该文件加载SimpleCV图像)?您有没有测量过平均截图需要多长时间?@Lenny有一些计时-“大约70毫秒(~14帧/秒)要捕获1680x1050像素屏幕,“我只能在OSX中获得带有pyscreenshot的黑屏。它是否会引发任何错误/警告?”?你能分享更多细节吗?如果你有视网膜显示器,它会缩放图像吗?我目前没有办法测试这个。当你尝试的时候会发生这种情况吗?我不明白为什么它会缩放图像。
#
# The Python Imaging Library
# $Id$
#
# screen grabber (macOS and Windows only)
#
# History:
# 2001-04-26 fl  created
# 2001-09-17 fl  use builtin driver, if present
# 2002-11-19 fl  added grabclipboard support
#
# Copyright (c) 2001-2002 by Secret Labs AB
# Copyright (c) 2001-2002 by Fredrik Lundh
#
# See the README file for information on usage and redistribution.
#

from . import Image

import sys
if sys.platform not in ["win32", "darwin"]:
    raise ImportError("ImageGrab is macOS and Windows only")

if sys.platform == "win32":
    grabber = Image.core.grabscreen
elif sys.platform == "darwin":
    import os
    import tempfile
    import subprocess


def grab(bbox=None):
    if sys.platform == "darwin":
        fh, filepath = tempfile.mkstemp('.png')
        os.close(fh)
        subprocess.call(['screencapture', '-x', filepath])
        im = Image.open(filepath)
        im.load()
        os.unlink(filepath)
    else:
        size, data = grabber()
        im = Image.frombytes(
            "RGB", size, data,
            # RGB, 32-bit line padding, origin lower left corner
            "raw", "BGR", (size[0]*3 + 3) & -4, -1
            )
    if bbox:
        im = im.crop(bbox)
    return im


def grabclipboard():
    if sys.platform == "darwin":
        fh, filepath = tempfile.mkstemp('.jpg')
        os.close(fh)
        commands = [
            "set theFile to (open for access POSIX file \""+filepath+"\" with write permission)",
            "try",
                "write (the clipboard as JPEG picture) to theFile",
            "end try",
            "close access theFile"
        ]
        script = ["osascript"]
        for command in commands:
            script += ["-e", command]
        subprocess.call(script)

        im = None
        if os.stat(filepath).st_size != 0:
            im = Image.open(filepath)
            im.load()
        os.unlink(filepath)
        return im
    else:
        debug = 0  # temporary interface
        data = Image.core.grabclipboard(debug)
        if isinstance(data, bytes):
            from . import BmpImagePlugin
            import io
            return BmpImagePlugin.DibImageFile(io.BytesIO(data))
        return data
from subprocess import call
import time
from time import gmtime, strftime

# Take screenshot every 10 seconds and store in the folder where the 
# code file is present on disk. To stop the script press Cmd+Z/C
def take_screen_shot():
    # save screen shots where
    call(["screencapture", "Screenshot" + strftime("%Y-%m-%d %H:%M:%S", gmtime()) + ".jpg"])



def build_screen_shot_base():
    while True:
        take_screen_shot()
        time.sleep(10)


build_screen_shot_base()