如何用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("未找到目标窗口")
关键说明
- DWM API原理:Windows对最小化窗口会维护一个缩略图副本,通过
DwmGetIconicThumbnail可以直接获取这个副本,无需窗口前台渲染。 - 兼容性限制:
- 必须启用桌面合成(Windows Vista及以上系统默认开启)。
- 游戏需运行在窗口化/窗口全屏模式,独占全屏模式下DWM无法生成缩略图。
- 部分反作弊软件可能拦截DWM调用,需测试游戏兼容性。
- 窗口句柄获取:如果窗口标题不固定,可以用
win32gui.EnumWindows遍历所有窗口,根据进程ID或类名筛选目标窗口。
内容的提问来源于stack exchange,提问作者Matteus Barbosa
相关产品推荐
相关产品推荐

