Pillow ImageGrab 模块

下面给你一个 Pillow(PIL Fork)中 ImageGrab 模块 的完整入门指南,包含截图功能、全屏/区域/窗口截取、跨平台支持、实时监控、OCR 配合、自动化脚本等高级应用。
(基于 Pillow ≥ 9.0,Python 3.8+)


1. 安装 Pillow(含抓屏支持)

# Windows / macOS / Linux(需额外依赖)
pip install --upgrade pillow

注意平台支持

  • Windows:原生支持
  • macOS:原生支持(Pillow ≥ 3.3)
  • Linux:需安装 xlib 依赖:
  pip install pillow
  sudo apt-get install python3-xlib    # Debian/Ubuntu

2. 基本导入

from PIL import ImageGrab

3. 核心功能一览

方法作用参数
ImageGrab.grab(bbox=None)截取屏幕bbox=(x1,y1,x2,y2)
ImageGrab.grabclipboard()读取剪贴板图像

4. 基础用法:截全屏

# 截取整个屏幕
img = ImageGrab.grab()
img.save("fullscreen.png")
print(f"分辨率: {img.size}")

5. 截取指定区域

# 左上角 (100,100) 到右下角 (500,400)
bbox = (100, 100, 500, 400)
img = ImageGrab.grab(bbox=bbox)
img.save("region.png")

坐标说明

  • (0,0) 是屏幕 左上角
  • 多显示器:负坐标表示左侧屏幕

6. 多显示器支持

from PIL import ImageGrab

# 获取所有显示器总尺寸
total_bbox = ImageGrab.grab().getbbox()  # (0, 0, 总宽, 总高)
print(f"多屏总尺寸: {total_bbox}")

# 截取第二个显示器(假设分辨率 1920x1080)
img = ImageGrab.grab(bbox=(1920, 0, 3840, 1080))
img.save("second_screen.png")

7. 实时截屏 + 保存为 GIF 动画

import time
from PIL import ImageGrab

def screen_record(duration=5, fps=10, output="screen.gif"):
    frames = []
    interval = 1 / fps
    start = time.time()

    while time.time() - start < duration:
        img = ImageGrab.grab()
        frames.append(img)
        time.sleep(interval)

    frames[0].save(
        output,
        save_all=True,
        append_images=frames[1:],
        duration=int(1000/fps),
        loop=0
    )
    print(f"录制完成: {output}")

# 录制 3 秒 10FPS
screen_record(3, 10, "demo.gif")

8. 截图 + OCR 文字识别(配合 pytesseract

pip install pytesseract
# Windows 需安装 Tesseract OCR 引擎:https://github.com/UB-Mannheim/tesseract/wiki
import pytesseract
from PIL import ImageGrab

# 配置 tesseract 路径(Windows)
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'

def ocr_region(bbox):
    img = ImageGrab.grab(bbox=bbox)
    text = pytesseract.image_to_string(img, lang='chi_sim+eng')  # 支持中英
    return text.strip()

# 识别屏幕中间区域文字
text = ocr_region((200, 200, 800, 600))
print("识别结果:", text)

9. 监控屏幕变化(自动截图)

import hashlib
from PIL import ImageGrab, ImageChops

def monitor_screen(bbox=None, interval=1, max_changes=10):
    prev = None
    changes = 0

    while changes < max_changes:
        current = ImageGrab.grab(bbox=bbox)

        if prev is not None:
            diff = ImageChops.difference(prev, current)
            if diff.getbbox():  # 有变化
                changes += 1
                current.save(f"change_{changes}.png")
                print(f"检测到变化 #{changes}")

        prev = current
        time.sleep(interval)

# 监控右下角区域
monitor_screen(bbox=(1000, 600, 1920, 1080), interval=2)

10. 读取剪贴板图像

def paste_from_clipboard():
    img = ImageGrab.grabclipboard()
    if isinstance(img, Image.Image):
        img.save("clipboard.png")
        print("剪贴板图像已保存")
    elif img is None:
        print("剪贴板无图像")
    else:
        print(f"剪贴板含文件: {img}")

paste_from_clipboard()

11. 高级技巧

11.1 截取特定窗口(Windows 推荐 pywin32

pip install pywin32
import win32gui
import win32ui
import win32con
from PIL import Image

def grab_window_by_title(title_contains):
    hwnd = win32gui.FindWindow(None, None)
    windows = []
    def enum_handler(hwnd, ctx):
        if win32gui.IsWindowVisible(hwnd):
            title = win32gui.GetWindowText(hwnd)
            if title_contains in title:
                windows.append((hwnd, title))
    win32gui.EnumWindows(enum_handler, None)

    if not windows:
        return None

    hwnd = windows[0][0]
    left, top, right, bot = win32gui.GetWindowRect(hwnd)
    w = right - left
    h = bot - top

    # 创建设备上下文
    hwndDC = win32gui.GetWindowDC(hwnd)
    mfcDC = win32ui.CreateDCFromHandle(hwndDC)
    saveDC = mfcDC.CreateCompatibleDC()

    saveBitMap = win32ui.CreateBitmap()
    saveBitMap.CreateCompatibleBitmap(mfcDC, w, h)
    saveDC.SelectObject(saveBitMap)

    saveDC.BitBlt((0,0), (w,h), mfcDC, (0,0), win32con.SRCCOPY)

    bmpinfo = saveBitMap.GetInfo()
    bmpstr = saveBitMap.GetBitmapBits(True)
    im = Image.frombuffer('RGB', (bmpinfo['bmWidth'], bmpinfo['bmHeight']), bmpstr, 'raw', 'BGRX', 0, 1)

    win32gui.DeleteObject(saveBitMap.GetHandle())
    saveDC.DeleteDC()
    mfcDC.DeleteDC()
    win32gui.ReleaseDC(hwnd, hwndDC)

    return im

# 截取记事本
img = grab_window_by_title("记事本")
if img:
    img.save("notepad.png")

11.2 自动截图脚本(定时任务)

import schedule
import time

def job():
    img = ImageGrab.grab()
    timestamp = time.strftime("%Y%m%d_%H%M%S")
    img.save(f"screenshots/{timestamp}.png")

schedule.every(10).minutes.do(job)

while True:
    schedule.run_pending()
    time.sleep(1)

12. 常见问题 & 解决方案

问题原因解决
ImportError: ImageGrab is not available on this platformLinux 未安装 python3-xlibpip install python3-xlib
截图全黑macOS 权限不足系统偏好设置 → 安全性与隐私 → 屏幕录制 → 勾选 Python
多屏坐标错误未考虑 DPI 缩放使用 ctypes.windll.shcore.GetScaleFactorForDevice(Windows)
grab() 卡死截图区域过大限制 bbox 或降低频率

13. 跨平台兼容封装

def cross_platform_grab(bbox=None):
    try:
        return ImageGrab.grab(bbox=bbox)
    except Exception as e:
        print(f"ImageGrab 失败: {e}")
        return None

# 使用
img = cross_platform_grab((0, 0, 800, 600))

14. 官方文档

  • https://pillow.readthedocs.io/en/stable/reference/ImageGrab.html

一键截图工具:grab_tool.py

#!/usr/bin/env python3
import argparse
from PIL import ImageGrab
import pyperclip
import os

def main():
    parser = argparse.ArgumentParser(description="屏幕截图工具")
    parser.add_argument("-r", "--region", nargs=4, type=int, metavar=('x1','y1','x2','y2'), help="指定区域")
    parser.add_argument("-c", "--clipboard", action="store_true", help="保存到剪贴板")
    parser.add_argument("-o", "--output", help="输出文件名")

    args = parser.parse_args()

    img = ImageGrab.grab(bbox=args.region)
    output = args.output or f"screenshot_{int(time.time())}.png"

    img.save(output)
    print(f"已保存: {output}")

    if args.clipboard:
        # Windows/macOS 自动复制到剪贴板
        try:
            import io
            output = io.BytesIO()
            img.convert("RGB").save(output, format='BMP')
            data = output.getvalue()[14:]  # 跳过 BMP 头
            import win32clipboard  # pip install pywin32
            win32clipboard.OpenClipboard()
            win32clipboard.EmptyClipboard()
            win32clipboard.SetClipboardData(win32clipboard.CF_DIB, data)
            win32clipboard.CloseClipboard()
            print("已复制到剪贴板")
        except:
            pass

if __name__ == "__main__":
    os.makedirs("screenshots", exist_ok=True)
    os.chdir("screenshots")
    main()

使用

python grab_tool.py -r 100 100 500 400 -c -o demo.png

需要我帮你实现 自动监控游戏界面、截图对比找物、自动化测试截图验证、热键截图 等功能吗?直接说需求,我给你完整代码!

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注