Capturing screenshots programmatically is useful for a variety of tasks: automated testing, monitoring dashboards, creating documentation, recording screen activity, or building desktop automation tools. Python provides several libraries for taking screenshots, from simple full-screen captures to targeted region captures. This guide covers multiple methods using pyautogui, Pillow, and mss, with practical examples for different use cases.
Method 1: Using PyAutoGUI
PyAutoGUI is a cross-platform GUI automation library that includes a simple screenshot function. It captures the entire screen and returns a PIL (Pillow) Image object.
Installation
pip install pyautogui
pip install PillowTaking a Full Screenshot
import pyautogui
screenshot = pyautogui.screenshot()
screenshot.save("full_screenshot.png")
print(f"Screenshot saved: {screenshot.size[0]}x{screenshot.size[1]} pixels")Output:
Screenshot saved: 1920x1080 pixelsYou can also save directly by passing a filename to screenshot():
import pyautogui
screenshot = pyautogui.screenshot("my_screenshot.png")Capturing a Specific Region
To capture only a portion of the screen, pass a region tuple (left, top, width, height):
import pyautogui
region_screenshot = pyautogui.screenshot(region=(100, 200, 400, 300))
region_screenshot.save("region_screenshot.png")
print(f"Region captured: {region_screenshot.size[0]}x{region_screenshot.size[1]} pixels")Output:
Region captured: 400x300 pixelsMethod 2: Using Pillow's ImageGrab
Pillow's ImageGrab module provides direct screen capture functionality. It is available on Windows and macOS.
Installation
pip install PillowFull Screen Capture
from PIL import ImageGrab
screenshot = ImageGrab.grab()
screenshot.save("pillow_screenshot.png")
print(f"Screenshot size: {screenshot.size}")Output:
Screenshot size: (1920, 1080)Capturing a Specific Region
Pass a bounding box tuple (left, upper, right, lower) to grab():
from PIL import ImageGrab
region = ImageGrab.grab(bbox=(0, 0, 500, 400))
region.save("pillow_region.png")
print(f"Region size: {region.size}")Output:
Region size: (500, 400)Method 3: Using MSS (Fast Multi-Screen Capture)
The mss library is optimized for speed and supports multi-monitor setups. It is significantly faster than PyAutoGUI and Pillow for repeated captures, making it ideal for screen recording or real-time monitoring.
Installation
pip install mssFull Screen Capture
import mss
with mss.mss() as sct:
screenshot = sct.grab(sct.monitors[1])
mss.tools.to_png(screenshot.rgb, screenshot.size, output="mss_screenshot.png")
print(f"Screenshot size: {screenshot.width}x{screenshot.height}")Output:
Screenshot size: 1920x1080Capturing All Monitors
import mss
with mss.mss() as sct:
print(f"Total monitors: {len(sct.monitors) - 1}")
for i, monitor in enumerate(sct.monitors[1:], start=1):
screenshot = sct.grab(monitor)
filename = f"monitor_{i}.png"
mss.tools.to_png(screenshot.rgb, screenshot.size, output=filename)
print(f"Monitor {i} saved: {screenshot.width}x{screenshot.height}")Output:
Total monitors: 2
Monitor 1 saved: 1920x1080
Monitor 2 saved: 1920x1080Capturing a Specific Region
import mss
with mss.mss() as sct:
region = {"top": 100, "left": 100, "width": 400, "height": 300}
screenshot = sct.grab(region)
mss.tools.to_png(screenshot.rgb, screenshot.size, output="mss_region.png")
print(f"Region captured: {screenshot.width}x{screenshot.height}")Output:
Region captured: 400x300Taking Multiple Screenshots at Intervals
To capture screenshots at regular intervals: useful for monitoring or time-lapse recording:
import pyautogui
import time
num_screenshots = 5
interval = 2 # seconds
for i in range(num_screenshots):
filename = f"screenshot_{i + 1}.png"
pyautogui.screenshot(filename)
print(f"Saved {filename}")
if i < num_screenshots - 1:
time.sleep(interval)
print(f"\nCaptured {num_screenshots} screenshots at {interval}-second intervals")Output:
Saved screenshot_1.png
Saved screenshot_2.png
Saved screenshot_3.png
Saved screenshot_4.png
Saved screenshot_5.png
Captured 5 screenshots at 2-second intervalsConverting a Screenshot to a NumPy Array
For image processing with OpenCV or other libraries, convert the screenshot to a NumPy array:
import pyautogui
import numpy as np
screenshot = pyautogui.screenshot()
img_array = np.array(screenshot)
print(f"Array shape: {img_array.shape}")
print(f"Data type: {img_array.dtype}")Output:
Array shape: (1080, 1920, 3)
Data type: uint8For use with OpenCV, convert from RGB to BGR:
import pyautogui
import numpy as np
import cv2
screenshot = pyautogui.screenshot()
img_array = np.array(screenshot)
img_bgr = cv2.cvtColor(img_array, cv2.COLOR_RGB2BGR)
cv2.imwrite("opencv_screenshot.png", img_bgr)Common Mistake: Not Converting Color Channels for OpenCV
PyAutoGUI and Pillow produce images in RGB format, while OpenCV expects BGR. Using the image directly without conversion results in swapped red and blue channels:
import pyautogui
import numpy as np
import cv2
screenshot = pyautogui.screenshot()
img_array = np.array(screenshot)
cv2.imwrite("wrong_colors.png", img_array)The saved image will have blue objects appearing red and red objects appearing blue.
The correct approach
img_bgr = cv2.cvtColor(img_array, cv2.COLOR_RGB2BGR)
cv2.imwrite("correct_colors.png", img_bgr)Method Comparison
| Library | Speed | Multi-Monitor | Region Capture | Platform |
|---|---|---|---|---|
pyautogui |
Moderate | No | Yes | Windows, macOS, Linux |
Pillow (ImageGrab) |
Moderate | Limited | Yes | Windows, macOS |
mss |
Fast | Yes | Yes | Windows, macOS, Linux |
| Use Case | Recommended Library |
|---|---|
| Quick single screenshot | pyautogui |
| Integration with image processing | Pillow (ImageGrab) |
| High-performance repeated captures | mss |
| Multi-monitor capture | mss |
| GUI automation with screenshots | pyautogui |
For simple, one-off screenshots, PyAutoGUI offers the easiest API. For performance-sensitive applications or multi-monitor setups, mss is the better choice. All three libraries are well-maintained and cross-platform (with minor limitations for Pillow on Linux).