Снимок экрана не захватывает то, что на экране
Я пытаюсь автоматически делать скриншоты, но в зависимости от того, как все происходит, я не всегда фиксирую то, что на самом деле на экране.
В качестве упражнения в 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
чтобы щелкнуть окно, которое я пытался сделать, когда оно станет видимым, чтобы убедиться, что оно активно, но это тоже не сработало.
У кого-нибудь есть мысли о том, как сделать скриншот активного окна?