在Mac OS X上用Python截图

7 投票
6 回答
22992 浏览
提问于 2025-04-16 08:59

PIL中的ImageGrab功能本来是最理想的选择。我想找类似的功能,特别是能够定义截图的范围。我在Mac OS X上找了一个库来实现这个功能,但一直没有找到合适的。我也没能找到任何示例代码来实现这个功能(也许可以用pyobjc?)。

6 个回答

8

虽然我知道这个讨论已经快五年了,但我还是想回答这个问题,希望能帮助到未来的人。

以下是我根据这个讨论中的一个回答找到的解决办法(感谢 ponty ): 通过 Python 脚本截屏 [Linux]

你可以在这里找到相关的代码库:https://github.com/ponty/pyscreenshot

安装方法:

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')
11

下面是如何使用PyObjC来捕捉和保存屏幕截图的方法,参考了我在这里的回答

你可以捕捉整个屏幕,或者指定一个区域来捕捉。如果你不需要那么复杂的功能,我建议直接使用screencapture这个命令(它功能更多、更稳定,而且速度更快——单单导入PyObjC就可能需要大约一秒钟)

import Quartz
import LaunchServices
from Cocoa import NSURL
import Quartz.CoreGraphics as CG


def screenshot(path, region = None):
    """region should be a CGRect, something like:

    >>> import Quartz.CoreGraphics as CG
    >>> region = CG.CGRectMake(0, 0, 100, 100)
    >>> sp = ScreenPixel()
    >>> sp.capture(region=region)

    The default region is CG.CGRectInfinite (captures the full screen)
    """

    if region is None:
        region = CG.CGRectInfinite

    # Create screenshot as CGImage
    image = CG.CGWindowListCreateImage(
        region,
        CG.kCGWindowListOptionOnScreenOnly,
        CG.kCGNullWindowID,
        CG.kCGWindowImageDefault)

    dpi = 72 # FIXME: Should query this from somewhere, e.g for retina displays

    url = NSURL.fileURLWithPath_(path)

    dest = Quartz.CGImageDestinationCreateWithURL(
        url,
        LaunchServices.kUTTypePNG, # file type
        1, # 1 image in file
        None
        )

    properties = {
        Quartz.kCGImagePropertyDPIWidth: dpi,
        Quartz.kCGImagePropertyDPIHeight: dpi,
        }

    # Add the image to the destination, characterizing the image with
    # the properties dictionary.
    Quartz.CGImageDestinationAddImage(dest, image, properties)

    # When all the images (only 1 in this example) are added to the destination, 
    # finalize the CGImageDestination object. 
    Quartz.CGImageDestinationFinalize(dest)


if __name__ == '__main__':
    # Capture full screen
    screenshot("/tmp/testscreenshot_full.png")

    # Capture region (100x100 box from top-left)
    region = CG.CGRectMake(0, 0, 100, 100)
    screenshot("/tmp/testscreenshot_partial.png", region=region)
16

虽然这不是你想要的完全解决方案,但在紧急情况下你可以试试这个:

os.system("screencapture screen.png")

然后用图像模块打开那个图片。不过我相信还有更好的办法。

撰写回答