ScreenshotNeo

BlogScreenshots on your device

How to Screenshot a Notepad Window with Python

Capture one visible Notepad window in Python with Pillow, find its HWND, handle common errors, and compare screen, region, and native Windows methods.

By the ScreenshotNeo team1 October 20266 min read

How to Screenshot a Notepad Window with Python

To screenshot only one visible Notepad window on Windows, use Pillow’s ImageGrab.grab(window=hwnd). The window value is the window’s Windows handle (HWND), so the process has two steps: find Notepad’s HWND, then pass it to Pillow. Windows support for this argument was added in Pillow 11.2.1.

Capture a Notepad window with Pillow

1. Install Pillow

python -m pip install "Pillow>=11.2.1"

Use a Windows desktop session with Notepad open and visible. The documented API targets a window HWND; it does not establish support for minimized windows, locked desktops, or headless sessions. Check your installed version if the window argument is rejected.

2. Find Notepad’s HWND and save the image

This script searches top-level windows for a title containing Notepad, captures the first visible match, and writes a PNG.

import ctypes
from ctypes import wintypes
from pathlib import Path

from PIL import ImageGrab

user32 = ctypes.windll.user32

EnumWindows = user32.EnumWindows
EnumWindowsProc = ctypes.WINFUNCTYPE(ctypes.c_bool, wintypes.HWND, wintypes.LPARAM)
GetWindowTextLengthW = user32.GetWindowTextLengthW
GetWindowTextW = user32.GetWindowTextW
IsWindowVisible = user32.IsWindowVisible


def find_window_title_contains(text: str) -> int | None:
    """Return the first visible top-level HWND whose title contains text."""
    result = None
    needle = text.casefold()

    @EnumWindowsProc
    def callback(hwnd, _lparam):
        nonlocal result
        if not IsWindowVisible(hwnd):
            return True

        length = GetWindowTextLengthW(hwnd)
        if length == 0:
            return True

        buffer = ctypes.create_unicode_buffer(length + 1)
        GetWindowTextW(hwnd, buffer, length + 1)
        if needle in buffer.value.casefold():
            result = hwnd
            return False
        return True

    EnumWindows(callback, 0)
    return result


hwnd = find_window_title_contains("Notepad")
if hwnd is None:
    raise RuntimeError("No visible Notepad window was found. Open Notepad first.")

image = ImageGrab.grab(window=hwnd)
out = Path("notepad-window.png")
image.save(out)
print(f"Saved {out} ({image.width}x{image.height}) from HWND {hwnd}")

The Pillow reference documents the window parameter as an HWND on Windows: ImageGrab reference. If several Notepad windows are open, make the title search more specific or enumerate all matching handles and choose one.

Use an exact title when needed

# Replace the contains check in the callback with:
if buffer.value == "Notes - Notepad":
    result = hwnd
    return False

Window titles vary by Windows version and by the file currently open. A contains search is usually more robust than an exact match.

How the HWND lookup works

  1. EnumWindows visits top-level windows.
  2. IsWindowVisible filters out hidden windows.
  3. GetWindowTextW reads each title.
  4. The matching HWND is passed to ImageGrab.grab(window=hwnd).
  5. Pillow returns an image object, which is saved with image.save().

The HWND is an operating-system identifier, not a pixel coordinate. That is why this method follows the chosen window when it moves or changes size, whereas a fixed screen region does not.

The HWND lookup identifies the Notepad window before Pillow captures it.
The HWND lookup identifies the Notepad window before Pillow captures it.

Capture the whole screen or a fixed region with PyAutoGUI

PyAutoGUI is simpler when you need the entire display or a known rectangle. Its documented screenshot function requires Pillow and accepts a region=(left, top, width, height) tuple. It does not select a window by title.

python -m pip install pyautogui
import pyautogui

# Entire visible display
screen = pyautogui.screenshot()
screen.save("screen.png")

# A known rectangle: left, top, width, height
region = pyautogui.screenshot(region=(100, 100, 900, 650))
region.save("notepad-region.png")

PyAutoGUI’s documentation gives roughly 100 milliseconds as an example capture time for a 1920×1080 screen; treat that as documentation guidance rather than a current-machine benchmark: Screenshot Functions.

Choose the right method

Method Best for Limit
Pillow ImageGrab.grab(window=hwnd) One specified visible Notepad window Requires a valid HWND and Pillow 11.2.1 or newer for Windows window capture
PyAutoGUI screenshot() Whole display capture Does not choose a window by title
PyAutoGUI region=... A stable, known rectangle Coordinates become wrong when the window moves, resizes, or display scaling changes
Snipping Tool Interactive human selection Requires Windows UI interaction
Windows.Graphics.Capture A native Windows application that needs display or application-window capture More implementation work than a short Python script
Window capture follows the selected window; region capture follows fixed screen coordinates.
Window capture follows the selected window; region capture follows fixed screen coordinates.

Use Windows Snipping Tool for an interactive capture

Windows Snipping Tool supports window capture through its documented ms-screenclip: launch protocol. It is useful when a person should select the Notepad window manually. Microsoft lists rectangle capture, freeform capture, window capture, screen recording, configurable modes, and optional auto-save in its protocol documentation: Launch Snipping Tool.

There is an important integration constraint: a response callback through redirect-uri requires an MSIX-packaged app. An unpackaged Win32 Python script cannot assume it will receive that callback.

Native Windows capture for larger applications

Windows.Graphics.Capture provides display or application-window capture and uses secure system UI so the user selects the item. It is intended for Windows desktop devices and Windows Mixed Reality immersive headsets. It is a better foundation for a full native application than for a small Pillow utility.

Common errors and fixes

Error or symptom Cause Fix
TypeError or unexpected window argument Older Pillow release Upgrade with python -m pip install --upgrade "Pillow>=11.2.1" and verify python -c "import PIL; print(PIL.__version__)".
No Notepad window found Notepad is closed, hidden, or the title does not contain the searched text Open a visible window, print all titles while debugging, or use a more suitable title match.
Black, blank, or incomplete image The window is minimized, covered by a protected surface, or the desktop session is unavailable Restore and activate Notepad in an interactive Windows session. The cited sources do not promise minimized or headless capture.
Wrong window selected Several titles match Use an exact title, inspect HWNDs, or add a selection rule such as process ID.
Region screenshot is offset Display scaling, multiple monitors, or a moved window Prefer HWND capture, or recalculate coordinates from the current window position and DPI settings.
Permission or access failure The target application runs at a higher integrity level Run both processes at compatible privilege levels where appropriate; avoid elevating unnecessarily.
File cannot be opened Output directory does not exist or is not writable Save to a known writable path and create its parent directory first.

Performance, reliability, and file choices

  • Capture only when needed. Repeated full-window PNGs consume more CPU, memory, and disk than occasional captures.
  • PNG is lossless and preserves text sharply. JPEG is smaller but can introduce artifacts around text; Pillow can save other formats when the chosen encoder supports them.
  • Keep the Notepad window visible and stable during capture. Moving or resizing it while the grab runs can produce an inconsistent result.
  • For unattended jobs, detect the HWND immediately before capture and verify that it is still valid. Log the title, HWND, output path, and image dimensions.
  • Do not treat a successful file write as proof that the correct window was captured. Review the selected title and, when needed, add a visual or dimension check.
  • Python’s Windows documentation currently describes Python 3.14 as supporting Windows 10 and newer; check your target interpreter and operating system before standardizing deployment: Using Python on Windows.

Or skip the browser setup

The Pillow and PyAutoGUI recipes above capture a local Windows desktop. If what you actually need is a screenshot of a web page, ScreenshotNeo provides a single HTTP request that returns PNG, JPEG, WebP, or PDF. It removes cookie and consent banners, newsletter popups, and chat widgets before capture. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing result. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.

See the ScreenshotNeo API documentation for all options.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
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)
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 buffer = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', buffer));

Every plan includes the features: 1,000 screenshots a month are free with no card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.

FAQ

Can Python capture a Notepad window by title without coordinates?

Yes. Find the window’s HWND with the Windows API, then pass it to Pillow’s ImageGrab.grab(window=hwnd).

Does PyAutoGUI select a window named Notepad?

No. Its documented calls capture the display or a coordinate region. Use Pillow with an HWND for title-based window selection.

Can this capture a minimized Notepad window?

The supplied documentation does not establish minimized-window support. Restore the window in a visible interactive desktop before capturing.

What Pillow version is required?

Pillow documents Windows support for the window argument beginning with version 11.2.1.

Should I use Snipping Tool from a Python script?

Use it for interactive user selection. If you need a programmatic callback through its documented protocol, the caller must be an MSIX-packaged app.