Skip to content
This repository has been archived by the owner on Apr 26, 2023. It is now read-only.

Commit

Permalink
Merge branch 'capture-hardware-accelerated-windows' of https://github…
Browse files Browse the repository at this point in the history
  • Loading branch information
Avasam committed Nov 3, 2021
2 parents 43480b8 + 8690800 commit 3ed7120
Showing 1 changed file with 23 additions and 15 deletions.
38 changes: 23 additions & 15 deletions src/capture_windows.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
from ctypes import windll
from ctypes.wintypes import LONG, RECT
from win32 import win32gui
import numpy as np
import win32ui
import win32con
import numpy as np

def capture_region(hwnd, rect):
# This is an undocumented nFlag value for PrintWindow
PW_RENDERFULLCONTENT = 0x00000002


def capture_region(hwnd: int, rect: RECT):
"""
Captures an image of the region for a window matching the given
parameters of the bounding box
Expand All @@ -13,24 +19,26 @@ def capture_region(hwnd, rect):
@return: The image of the region in the window in BGRA format
"""

width = rect.right - rect.left
height = rect.bottom - rect.top
width: LONG = rect.right - rect.left
height: LONG = rect.bottom - rect.top

wDC = win32gui.GetWindowDC(hwnd)
dcObj = win32ui.CreateDCFromHandle(wDC)
cDC = dcObj.CreateCompatibleDC()
windowDC = win32gui.GetWindowDC(hwnd)
dcObject = win32ui.CreateDCFromHandle(windowDC)
compatibleDC = dcObject.CreateCompatibleDC()
bmp = win32ui.CreateBitmap()
bmp.CreateCompatibleBitmap(dcObj, width, height)
cDC.SelectObject(bmp)
cDC.BitBlt((0, 0), (width, height), dcObj, (rect.left, rect.top), win32con.SRCCOPY)
bmp.CreateCompatibleBitmap(dcObject, width, height)
compatibleDC.SelectObject(bmp)
compatibleDC.BitBlt((0, 0), (width, height), dcObject, (rect.left, rect.top), win32con.SRCCOPY)

# Force render full content through PrintWindow. Workaround to capture hardware accelerated windows
windll.user32.PrintWindow(hwnd, dcObject.GetSafeHdc(), PW_RENDERFULLCONTENT)

img = bmp.GetBitmapBits(True)
img = np.frombuffer(img, dtype='uint8')
img: np._BufferType = np.frombuffer(bmp.GetBitmapBits(True), dtype='uint8')
img.shape = (height, width, 4)

dcObj.DeleteDC()
cDC.DeleteDC()
win32gui.ReleaseDC(hwnd, wDC)
dcObject.DeleteDC()
compatibleDC.DeleteDC()
win32gui.ReleaseDC(hwnd, windowDC)
win32gui.DeleteObject(bmp.GetHandle())

return img

0 comments on commit 3ed7120

Please sign in to comment.