You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python脚本抓取Windows非活跃/最小化窗口截图?

如何用Python抓取Windows系统中最小化窗口的截图

Windows系统中,最小化窗口默认会被系统暂停前台绘制,常规的GDI截图方法无法获取其内容。要实现这一需求,必须借助**桌面窗口管理器(DWM)**的API来获取窗口的标志性缩略图(Iconic Bitmap),这是Windows专为最小化窗口保留的渲染内容。以下是具体实现方案:

依赖准备

首先安装所需的Python库:

pip install pywin32 pillow

实现代码

该脚本通过DwmGetIconicThumbnail API获取最小化窗口的缩略图,同时兼容非最小化窗口的常规截图:

import win32gui
import win32ui
import win32con
from PIL import Image
import ctypes
from ctypes import wintypes

# 加载DWM API
dwmapi = ctypes.WinDLL("dwmapi")

# DWM属性常量
DWMWA_HAS_ICONIC_BITMAP = 10

def get_minimized_window_screenshot(hwnd):
    # 获取窗口尺寸
    rect = win32gui.GetWindowRect(hwnd)
    width = rect[2] - rect[0]
    height = rect[3] - rect[1]

    # 创建内存DC和位图用于存储截图
    hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(hwnd))
    memdc = hdc.CreateCompatibleDC()
    bmp = win32ui.CreateBitmap()
    bmp.CreateCompatibleBitmap(hdc, width, height)
    memdc.SelectObject(bmp)

    if win32gui.IsIconic(hwnd):
        # 检查窗口是否生成了标志性缩略图
        has_iconic_bmp = ctypes.c_int()
        dwmapi.DwmGetWindowAttribute(
            hwnd,
            DWMWA_HAS_ICONIC_BITMAP,
            ctypes.byref(has_iconic_bmp),
            ctypes.sizeof(has_iconic_bmp)
        )

        if has_iconic_bmp.value:
            # 刷新并获取缩略图到内存DC
            dwmapi.DwmInvalidateIconicBitmaps(hwnd)
            dwmapi.DwmGetIconicThumbnail(
                hwnd,
                width,
                height,
                memdc.GetSafeHdc(),
                ctypes.byref(ctypes.c_int())
            )
    else:
        # 非最小化窗口,使用常规BitBlt截图
        memdc.BitBlt((0, 0), (width, height), hdc, (0, 0), win32con.SRCCOPY)

    # 将位图转换为PIL图像
    bmp_info = bmp.GetInfo()
    bmp_str = bmp.GetBitmapBits(True)
    img = Image.frombuffer(
        "RGB",
        (bmp_info["bmWidth"], bmp_info["bmHeight"]),
        bmp_str,
        "raw",
        "BGRX",
        0,
        1
    )

    # 清理资源
    win32gui.ReleaseDC(hwnd, hdc.GetSafeHdc())
    memdc.DeleteDC()
    bmp.DeleteObject()

    return img

# 使用示例:替换为你的游戏窗口标题
target_window_title = "游戏客户端窗口标题"
hwnd = win32gui.FindWindow(None, target_window_title)

if hwnd:
    screenshot = get_minimized_window_screenshot(hwnd)
    screenshot.save("game_window_screenshot.png")
else:
    print("未找到目标窗口")

关键说明

  1. DWM API原理:Windows对最小化窗口会维护一个缩略图副本,通过DwmGetIconicThumbnail可以直接获取这个副本,无需窗口前台渲染。
  2. 兼容性限制:
    • 必须启用桌面合成(Windows Vista及以上系统默认开启)。
    • 游戏需运行在窗口化/窗口全屏模式,独占全屏模式下DWM无法生成缩略图。
    • 部分反作弊软件可能拦截DWM调用,需测试游戏兼容性。
  3. 窗口句柄获取:如果窗口标题不固定,可以用win32gui.EnumWindows遍历所有窗口,根据进程ID或类名筛选目标窗口。

内容的提问来源于stack exchange,提问作者Matteus Barbosa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 17:02:47