可能是Python中最快的捕获窗口画面的方法

发布时间:

更新时间:

对比了其他几种方式,使用 win32API 可能是目前 python 下最快的方案,我电脑单纯截图速度 0.01-0.02s,

可以后台捕获,可以移动窗口位置

如果是单纯地捕获窗口再进行其他处理,不用将画面写到视频文件里。

使用 conda 安装
conda install -c anaconda pywin32

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import time
import win32gui
import win32ui
import win32con
import cv2
import numpy as np

# 录屏调用以下方法
def videoRecordInit(fps, size, filename):
# 创建视频编码器
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(filename, fourcc, fps, size)
return out


def videoRecordWrite(out, frame):
# 将帧写入视频流
out.write(frame)

# 释放
def videoRecordRelease(out):
out.release()


# 查找窗口句柄
handle = win32gui.FindWindow(None, "应用程序名")

# 获取屏幕DC
hdc = win32gui.GetDC(handle)

# 创建设备上下文DC
dc = win32ui.CreateDCFromHandle(hdc)

# 创建内存设备上下文DC
mem_dc = dc.CreateCompatibleDC()

# 获取窗口大小
left, top, right, bottom = win32gui.GetWindowRect(handle)
width = right - left
height = bottom - top

# 设置帧率
fps = 30
# 计算每帧之间的延迟时间
delay = 1 / fps

# 要录屏时
out = videoRecordInit(fps, (width, height), 'output.mp4')

# 循环遍历每个帧
while True:

# begin = time.time()

# 创建位图对象
bitmap = win32ui.CreateBitmap()
bitmap.CreateCompatibleBitmap(dc, width, height)

# 将位图对象选入内存设备上下文DC
mem_dc.SelectObject(bitmap)

# 将窗口截图复制到内存设备上下文DC
mem_dc.BitBlt((0, 0), (width, height), dc, (0, 0), win32con.SRCCOPY)

# 将位图对象转换为numpy数组
bmp_info = bitmap.GetInfo()
bmp_str = bitmap.GetBitmapBits(True)
img = np.fromstring(bmp_str, dtype='uint8')
img = img.reshape((bmp_info['bmHeight'], bmp_info['bmWidth'], 4))

# 转换颜色空间
img = img[:, :, :3]

# 录制
videoRecordWrite(out, img)

# 显示截图
cv2.imshow('frame', img)

# 若要设置帧数
time.sleep(delay)

# 查看速度
# end = time.time()
# print(end-begin)

# 按下q键退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break

# 释放所有对象
dc.DeleteDC()
mem_dc.DeleteDC()
win32gui.ReleaseDC(handle, hdc)
win32gui.DeleteObject(bitmap.GetHandle())
cv2.destroyAllWindows()
videoRecordRelease()
请吃小笼包
支付宝 | Alipay
微信 | Wechat