首页 > 解决方案 > 屏幕截图没有捕捉屏幕上的内容

问题描述

我正在尝试自动截取屏幕截图,但根据导航的方式,我并不总是捕捉屏幕上的实际内容。

作为 ML 的一个练习,我正在尝试编写一个机器人来玩赛车游戏,并且在玩游戏时它应该每秒左右截取屏幕截图并记录遥测数据。我pynput用来导航 GUI 和pyvjoy控制汽车。游戏有一个菜单屏幕,您可以在其中选择汽车和赛道,然后单击开始活动。此时菜单屏幕变为加载屏幕,并且在加载屏幕上另一个进程和窗口打开,其中发生了比赛。点击 Alt+Tab 显示两个单独的窗口,任务管理器显示 2 个进程。

当我导航到事件窗口后,机器人开始、失败并重新开始比赛时,没有离开事件窗口,它正在正确保存屏幕截图。但是一旦我将它更改为从菜单屏幕开始,选择一个曲目,“比赛”几次,退出事件回到菜单屏幕,选择下一个曲目,等等,而不是获取屏幕截图比赛时,它会截取菜单加载屏幕的屏幕截图,即使它在屏幕上不可见。

这是基本代码,使用PIL,在机器人的第一个化身中工作,但不是轨道选择一个。

image = np.array(ImageGrab.grab())
im = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_RGB2GRAY))
im.save(str(time.time()) + '.png')

然后我尝试pyautogui了但仍然有相同的行为

image = np.array(pyautogui.screenshot())
im = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_RGB2GRAY))
im.save(str(time.time()) + '.png')

我试图模拟键盘按键来捕获屏幕截图,然后使用它,但我发现剪贴板中没有图像。

import pynput.keyboard as kbd
import pynput.mouse as mus

keyboard = kbd.Controller()
mouse = mus.Controller()

keyboard.press(kbd.Key.print_screen)
time.sleep(0.01)
keyboard.release(kbd.Key.print_screen)
image = np.array(ImageGrab.grabclipboard())
im = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_RGB2GRAY))
im.save(str(time.time()) + '.png')

我注意到,如果我在运行期间使用 Alt+Tab 在窗口之间移动,它会开始工作,所以我曾经win32gui.SetForegroundWindow(win32gui.FindWindow('acsw', None))将我关心的活动窗口与其他先前尝试的屏幕捕获代码结合起来,但仍然没有。我还单独使用了 win32gui,并获得了与其他所有内容相同的结果。

hwnd = win32gui.FindWindow('acsw', None)
dataBitMap = win32ui.CreateBitmapFromHandle()
w=1920
h=1080
dataBitMap.CreateCompatibleBitmap(dcObj, w, h)
cDC.SelectObject(dataBitMap)
cDC.BitBlt((0,0),(w, h) , dcObj, (0,0), win32con.SRCCOPY)
dataBitMap.SaveBitmapFile(cDC, str(time.time())+'.bmp')
# Free Resources
dcObj.DeleteDC()
cDC.DeleteDC()
win32gui.ReleaseDC(hwnd, wDC)
win32gui.DeleteObject(dataBitMap.GetHandle())

我还尝试使用pynput单击我试图捕获的窗口,一旦它可见以确保它处于活动状态,但这也不起作用。

有人对如何截取活动窗口有任何想法吗?

标签: pythonpython-imaging-libraryscreenshotwin32guipyautogui

解决方案


推荐阅读