ScreenshotNeo

BlogScreenshots on your device

How to Take Unix Screenshots from Python on a Windows PC

Learn whether you need a Windows or WSL capture, then use PyAutoGUI, MSS, Pillow, or a screenshot API with working Python code.

By the ScreenshotNeo team1 October 20268 min read

Short answer: “Unix screenshots from Python on a Windows PC” can mean two different things. If you need the Windows desktop, run Python with the Windows interpreter and use a Windows-capable capture library. If you need a Linux display running under WSL, run Python inside that Linux environment and make sure its X11 or Wayland display is available. A Linux screenshot call does not automatically capture the Windows host desktop.

For a basic Windows capture, PyAutoGUI is the shortest path. For selecting monitors or rectangular regions and processing pixel buffers, MSS is a better fit. Pillow’s ImageGrab can capture screens too, with documented Linux fallbacks. WSL 2 and WSLg can run Linux GUI applications on Windows, but that does not turn a WSL capture into a host-desktop capture.

1. Decide which display you are capturing

Requirement Run Python where? Typical choice
Entire Windows desktop Windows Python PyAutoGUI or MSS
One Windows monitor or region Windows Python MSS
Linux GUI inside WSL Linux Python in WSL MSS, PyAutoGUI, or Pillow
Remote or web page screenshot Any environment with network access Screenshot API

Ask the practical question before installing anything: Do you need a screenshot of the Windows desktop, or of a Linux display running in WSL? The answer determines the display server, dependencies, and process that must own the capture.

2. Capture the Windows desktop with PyAutoGUI

PyAutoGUI documents screenshot calls that return a Pillow image. Passing a filename saves the image directly. Screenshot support requires Pillow; the project’s Linux instructions also identify scrot as a dependency for Linux screenshots. See the PyAutoGUI screenshot documentation and installation documentation.

Install

py -m pip install pyautogui

Save a full desktop screenshot

import pyautogui

image = pyautogui.screenshot('windows-desktop.png')
print(image.size)

Run this with the Windows interpreter that has PyAutoGUI installed. The image object can also be edited or saved in another format through Pillow:

import pyautogui

image = pyautogui.screenshot()
image.save('windows-desktop.jpg', quality=90)

Confirm which interpreter is running

import sys
print(sys.executable)
print(sys.platform)

On Windows, sys.platform should identify a Windows runtime. This check prevents a common mistake: installing a package in WSL and then executing a different Windows Python, or the reverse.

3. Capture a monitor or region with MSS

MSS documents separate Windows and GNU/Linux backends, monitor enumeration, region capture, and access to raw screenshot data. Its examples also show conversion to Pillow images. Read the MSS usage documentation and MSS examples.

Install

py -m pip install mss pillow

Capture the first monitor

from mss import MSS

with MSS() as capture:
    image = capture.grab(capture.monitors[1])
    print(image.size)
    image.save('monitor-1.png')

capture.monitors[0] represents the virtual bounding area across monitors. Entries starting at index 1 represent individual monitors. Print the list when you need to choose a specific display:

from mss import MSS

with MSS() as capture:
    for index, monitor in enumerate(capture.monitors):
        print(index, monitor)

Capture a rectangular region

from mss import MSS

region = {'top': 100, 'left': 200, 'width': 800, 'height': 600}

with MSS() as capture:
    shot = capture.grab(region)
    shot.save('region.png')

Coordinates are relative to the desktop coordinate system exposed by the active backend. Multi-monitor layouts can include negative coordinates when a monitor sits to the left or above the primary display, so inspect the monitor dictionaries instead of assuming that every screen starts at (0, 0).

4. Capture a Linux or Unix display inside WSL

Install and run the capture library inside the Linux distribution that owns the display. MSS uses the display identified by DISPLAY on Linux by default, and its API allows display or backend selection. A headless shell, missing display server, or X11/Wayland mismatch can make a screenshot fail even when the Python import succeeds.

Check the display environment

echo "$DISPLAY"
echo "$WAYLAND_DISPLAY"
python3 -c "import sys; print(sys.platform)"

If both display variables are empty, there may be no GUI display available to capture. If a variable points to a display that the process cannot access, fix the WSLg or display-server setup before changing Python code.

MSS in Linux Python

python3 -m pip install mss pillow
from mss import MSS

with MSS() as capture:
    print(capture.monitors)
    shot = capture.grab(capture.monitors[1])
    shot.save('linux-display.png')

PyAutoGUI in Linux Python

python3 -m pip install pyautogui
# Install scrot using your distribution's package manager when required.
import pyautogui

pyautogui.screenshot('wsl-display.png')

Pillow ImageGrab

Pillow’s ImageGrab documentation describes screen capture and Linux fallback programs under the documented X11 condition, including gnome-screenshot, grim, and spectacle. Use the fallback that matches the display system installed in your distribution.

from PIL import ImageGrab

image = ImageGrab.grab()
image.save('pillow-display.png')

5. Understand WSLg and the Windows boundary

Microsoft describes WSL as providing “bidirectional interop between Windows and Linux” in its WSL interop documentation. WSL can launch Windows executables from a Linux shell by using the .exe extension. That is an integration building block, not a ready-made host screenshot solution.

Microsoft’s Linux GUI apps with WSL documentation says WSL 2 supports X11 and Wayland applications in an integrated Windows desktop experience. The documented prerequisites include Windows 10 Build 19044 or later, or Windows 11, and the feature requires WSL 2. Microsoft also explains that this is not a full Linux desktop environment.

Therefore:

  • A Linux capture call normally sees the Linux display exposed to that process.
  • It does not establish that the call can see every window on the Windows host.
  • To capture the Windows desktop while orchestration starts in WSL, invoke a Windows-side capture program and explicitly handle its output path or bytes.

Possible cross-boundary pattern

# From WSL, launch a Windows Python script.
python.exe C:\\capture\\windows_capture.py

Validate this arrangement in your own setup. Permissions, path translation, the active interactive session, and whether the process is attached to the intended desktop all matter.

6. Select the library for the job

Need Recommended documented path Watch for
One quick Windows screenshot PyAutoGUI Pillow installation and interactive desktop
Monitor selection or regions MSS Coordinate systems and display backend
Pillow-based processing ImageGrab Linux fallback programs and X11 conditions
Linux GUI in WSL Run code inside WSL WSL 2, WSLg, DISPLAY/WAYLAND_DISPLAY

This is a capability comparison, not a universal speed ranking. The reviewed sources do not establish a current cross-library benchmark for your hardware.

7. Troubleshooting

“ModuleNotFoundError” after installation

Cause: pip installed into a different interpreter than the one running the script.

Fix: install through that interpreter and print sys.executable:

python -m pip install pyautogui mss pillow
python -c "import sys; print(sys.executable)"

PyAutoGUI reports that screenshot support is unavailable

Cause: Pillow is missing, or the Linux screenshot dependency documented by PyAutoGUI is absent.

Fix: install Pillow in the active environment. On Linux, install scrot when the PyAutoGUI documentation calls for it.

MSS returns a display or backend error

Cause: no accessible display, an incorrect DISPLAY, or a backend mismatch.

Fix: inspect DISPLAY and WAYLAND_DISPLAY, run the process inside the GUI-capable WSL session, and confirm that the selected monitor or backend exists.

The screenshot is blank or captures the wrong desktop

Cause: the process is running in a headless session, under another user, or on the Linux side while you expected the Windows host.

Fix: identify the target first. Run Windows capture code with Windows Python for the Windows desktop; run Linux capture code where the intended Linux display is available.

Only part of a multi-monitor setup appears

Cause: the code captured one monitor or a region rather than the virtual desktop.

Fix: inspect capture.monitors. Use index 0 for the virtual area or select the required monitor entry and account for negative coordinates.

WSL can launch a GUI app but cannot capture the Windows desktop

Cause: WSLg exposes Linux GUI applications; it does not promise host-wide Windows desktop capture.

Fix: run a Windows-side capture implementation and transfer the resulting file or bytes across the boundary.

8. Reliability, performance, and cost considerations

  • Reliability: keep the capture process attached to the intended interactive desktop and avoid assuming that package installation implies display access.
  • Multi-monitor correctness: enumerate monitors at runtime; do not hard-code a single origin or resolution.
  • Pixel processing: MSS exposes screenshot data suitable for processing and documented conversion to Pillow images. Save only the format and dimensions your downstream step needs.
  • Performance: no reviewed source establishes a hardware-independent winner. Measure your own workload if capture frequency matters.
  • Headless automation: desktop libraries need a real, accessible display. For web pages, a remote screenshot API avoids local display-server setup.
  • Cost: PyAutoGUI, MSS, and Pillow are software packages; this workflow does not require a physical capture card or other hardware.

9. Or skip the browser setup

If the thing you need is a screenshot of a web page rather than the Windows desktop or a WSL GUI, ScreenshotNeo provides a single HTTP request. Its API accepts a URL and returns PNG, JPEG, WebP, or PDF. Before capture it accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled.

Only clean shots are billed. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and billing state. ScreenshotNeo also provides an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.

See the ScreenshotNeo API documentation for all options, including full-page capture, element selectors, device presets, custom CSS and JavaScript, waits, request blocking, cookies, headers, geolocation, caching, signed links, asynchronous jobs, bulk capture, and usage reporting.

cURL

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)

Node.js

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = Buffer.from(await res.arrayBuffer());
require('fs').writeFileSync('shot.webp', data);

Free usage includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan. Create a free ScreenshotNeo account.

10. FAQ

Can Python in WSL screenshot my whole Windows desktop?

Do not assume it can. WSL interop lets Linux launch Windows executables, but a Linux display capture normally targets the Linux display. Use a Windows-side capture process for the Windows desktop and validate the handoff.

Should I use PyAutoGUI or MSS?

Use PyAutoGUI for a compact full-screen call. Use MSS when monitor selection, regions, or pixel-oriented processing are central.

Does WSL2 automatically provide a Linux desktop?

No. WSLg supports Linux GUI applications in an integrated Windows experience, but Microsoft documents it as different from a full Linux desktop. Your capture still needs an accessible display.

Can I capture a web page without opening a local browser?

Yes. ScreenshotNeo accepts the page URL over HTTP and handles browser setup, consent cleanup, waits, and output formats for you.