Take a screenshot in Python on Mac OS X

An ImageGrab from PIL would be ideal. I am looking for similar functionality, in particular the ability to define the bounding box of the screen. I was looking for a library to do this on Mac OS X, but no luck. I also could not find any sample code for this (perhaps pyobjc?).

+6
python screenshot macos
source share
6 answers

While not quite what you want, as a last resort, you can simply use:

os.system("screencapture screen.png") 

Then open this image using the Image module. I am sure that a better solution exists.

+16
source share

Here's how to capture and save a screenshot from PyObjC based on my answer here

You can capture the entire screen or specify the area to capture. If you do not need to do this, I would recommend just calling the screencapture command (more functions, more reliable and faster), the initial import of PyObjC may take about a second)

 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, eg 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) 
+8
source share

Although I understand that this stream is close to five years, I respond to this in the hope that it will help people in the future.

Here's what worked for me, based on the answer in this thread (credit goes ponty ): Take a screenshot through a python script. [Linux]

https://github.com/ponty/pyscreenshot

Installation:

 easy_install pyscreenshot 

Example:

 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') 
+5
source share

The pillow has since added ImageGrab support for macOS!

However, this is not in version v2.9 (the latter at the moment), so I just added this file to my local module.

The code is as follows:

 # # 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 
+1
source share

I found that using webkit2png was the most convenient solution for me on OS X.

 brew install webkit2png webkit2png http://stackoverflow.com 
0
source share
 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() 
0
source share

All Articles