Python调用Win32 API实现后台窗口与桌面截图详解

拾光
拾光
发布时间:2026-10-14| 2人浏览过
原创

本文详细介绍如何使用Python调用Win32接口进行截图。涵盖后台窗口截图(需保持非最小化状态)及全桌面截图两种场景,通过获取窗口句柄、设备描述表及位图操作实现图像捕获。文中提供完整代码示例,包括环境依赖安装、句柄获取、内存位图创建及OpenCV保存显示流程,适用于Windows平台下的自动化测试与图像采集需求。

环境依赖与库安装

在开始编写代码之前,需要确保Python环境及必要的第三方库已正确安装。根据示例,建议使用Python 3.7.1版本,并通过pip安装指定版本的依赖库。具体命令包括安装pywin32(版本224)、numpy(版本1.15.3)、opencv-python(版本3.4.2.16)、opencv-contrib-python(版本3.4.2.16)以及Pillow-PIL(版本0.1.dev0)。这些库分别用于Windows API调用、数组处理、图像格式转换与保存以及图像处理。


#版本python 3.7.1
pip install pywin32==224
pip install numpy==1.15.3
pip install opencv-python==3.4.2.16
pip install opencv-contrib-python==3.4.2.16
pip install Pillow-PIL==0.1.dev0

后台窗口截图实现

针对后台窗口进行截图时,首要条件是目标窗口不能处于最小化状态。代码首先利用win32gui.FindWindow函数,通过窗口类名(如NotePad)获取窗口句柄hWnd。若需获取其他类型窗口的类名,可借助Visual Studio的SPY++工具进行查看。接着,使用win32gui.GetWindowRect获取窗口的左上角和右下角坐标,进而计算出窗口的宽度width和高度height。随后,通过GetWindowDC获取覆盖整个窗口(含非客户区、标题栏、菜单及边框)的设备环境句柄hWndDC,并基于此创建内存设备描述表mfcDC和saveDC。


#对后台窗口截图
import win32gui, win32ui, win32con
from ctypes import windll
from PIL import Image
import cv2
import numpy
 
#获取后台窗口的句柄,注意后台窗口不能最小化
hWnd = win32gui.FindWindow("NotePad",None) #窗口的类名可以用Visual Studio的SPY++工具获取
#获取句柄窗口的大小信息
left, top, right, bot = win32gui.GetWindowRect(hWnd)
width = right - left
height = bot - top
#返回句柄窗口的设备环境,覆盖整个窗口,包括非客户区,标题栏,菜单,边框
hWndDC = win32gui.GetWindowDC(hWnd)
#创建设备描述表
mfcDC = win32ui.CreateDCFromHandle(hWndDC)
#创建内存设备描述表
saveDC = mfcDC.CreateCompatibleDC()
#创建位图对象准备保存图片
saveBitMap = win32ui.CreateBitmap()
#为bitmap开辟存储空间
saveBitMap.CreateCompatibleBitmap(mfcDC,width,height)
#将截图保存到saveBitMap中
saveDC.SelectObject(saveBitMap)
#保存bitmap到内存设备描述表
saveDC.BitBlt((0,0), (width,height), mfcDC, (0, 0), win32con.SRCCOPY)
 
#如果要截图到打印设备:
###最后一个int参数:0-保存整个窗口,1-只保存客户区。如果PrintWindow成功函数返回值为1
#result = windll.user32.PrintWindow(hWnd,saveDC.GetSafeHdc(),0)
#print(result) #PrintWindow成功则输出1
 
#保存图像
##方法一:windows api保存
###保存bitmap到文件
saveBitMap.SaveBitmapFile(saveDC,"img_Winapi.bmp")
 
##方法二(第一部分):PIL保存
###获取位图信息
bmpinfo = saveBitMap.GetInfo()
bmpstr = saveBitMap.GetBitmapBits(True)
###生成图像
im_PIL = Image.frombuffer('RGB',(bmpinfo['bmWidth'],bmpinfo['bmHeight']),bmpstr,'raw','BGRX',0,1)
##方法二(后续转第二部分)
 
##方法三(第一部分):opencv+numpy保存
###获取位图信息
signedIntsArray = saveBitMap.GetBitmapBits(True)
##方法三(后续转第二部分)
 
#内存释放
win32gui.DeleteObject(saveBitMap.GetHandle())
saveDC.DeleteDC()
mfcDC.DeleteDC()
win32gui.ReleaseDC(hWnd,hWndDC)
 
##方法二(第二部分):PIL保存
###PrintWindow成功,保存到文件,显示到屏幕
im_PIL.save("im_PIL.png") #保存
im_PIL.show() #显示
 
##方法三(第二部分):opencv+numpy保存
###PrintWindow成功,保存到文件,显示到屏幕
im_opencv = numpy.frombuffer(signedIntsArray, dtype = 'uint8')
im_opencv.shape = (height, width, 4)
cv2.cvtColor(im_opencv, cv2.COLOR_BGRA2RGB)
cv2.imwrite("im_opencv.jpg",im_opencv,[int(cv2.IMWRITE_JPEG_QUALITY), 100]) #保存
cv2.namedWindow('im_opencv') #命名窗口
cv2.imshow("im_opencv",im_opencv) #显示
cv2.waitKey(0)
cv2.destroyAllWindows()

内存位图创建与数据复制

在内存中创建位图对象saveBitMap,为其分配与窗口大小一致的存储空间,并通过SelectObject将其选入内存设备描述表。利用BitBlt函数将源设备描述表mfcDC的内容复制到目标内存设备描述表saveDC中,从而实现截图数据的内存保存。此步骤完成了图像数据的捕获,但尚未转换为可视格式。

图像格式转换与保存显示

截图数据保存至内存后,需进行格式转换与保存。通过获取位图的像素数据数组signedIntsArray,利用numpy将其转换为uint8类型的数组im_opencv,并重塑形状为(height, width, 4)以包含Alpha通道。使用cv2.cvtColor将BGRA格式转换为RGB格式,最后通过cv2.imwrite将图像保存为JPEG文件(质量设为100),并使用cv2.imshow在命名窗口中显示截图。注意,若使用PrintWindow函数,最后一个参数为0时保存整个窗口,为1时仅保存客户区,成功时返回值为1。

全桌面截图实现


import win32gui
import win32ui
import win32con
import win32api
 
# 获取桌面
hdesktop = win32gui.GetDesktopWindow()
# 分辨率适应
width = win32api.GetSystemMetrics(win32con.SM_CXVIRTUALSCREEN)
height = win32api.GetSystemMetrics(win32con.SM_CYVIRTUALSCREEN)
left = win32api.GetSystemMetrics(win32con.SM_XVIRTUALSCREEN)
top = win32api.GetSystemMetrics(win32con.SM_YVIRTUALSCREEN)
# 创建设备描述表
desktop_dc = win32gui.GetWindowDC(hdesktop)
img_dc = win32ui.CreateDCFromHandle(desktop_dc)
# 创建一个内存设备描述表
mem_dc = img_dc.CreateCompatibleDC()
# 创建位图对象
screenshot = win32ui.CreateBitmap()
screenshot.CreateCompatibleBitmap(img_dc, width, height)
mem_dc.SelectObject(screenshot)
# 截图至内存设备描述表
mem_dc.BitBlt((0, 0), (width, height), img_dc, (0, 0), win32con.SRCCOPY)
# 将截图保存到文件中
screenshot.SaveBitmapFile(mem_dc, 'screenshot.bmp')
# 内存释放
mem_dc.DeleteDC()
win32gui.DeleteObject(screenshot.GetHandle())

上述内容展示了Python调用Win32接口对后台窗口进行截图的完整流程。如需了解更多关于Python调用Win32接口的技术资料,建议参考本站其他相关文章。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。