Initial
This commit is contained in:
136
window_capture.py
Normal file
136
window_capture.py
Normal file
@@ -0,0 +1,136 @@
|
||||
import numpy as np
|
||||
import win32con
|
||||
import win32gui
|
||||
import win32ui
|
||||
from config_file import UserConfigs
|
||||
|
||||
|
||||
class WindowCapture:
|
||||
|
||||
# properties
|
||||
w = 0
|
||||
h = 0
|
||||
hwnd = None
|
||||
cropped_x = 0
|
||||
cropped_y = 0
|
||||
offset_x = 0
|
||||
offset_y = 0
|
||||
|
||||
# constructor
|
||||
def __init__(self, window_name, area, config):
|
||||
# find the handle for the window we want to capture.
|
||||
# if no window name is given, capture the entire screen
|
||||
if window_name is None:
|
||||
self.hwnd = win32gui.GetDesktopWindow()
|
||||
else:
|
||||
self.hwnd = win32gui.FindWindow(None, window_name)
|
||||
if not self.hwnd:
|
||||
raise Exception('Window not found: {}'.format(window_name))
|
||||
|
||||
if area == "poison":
|
||||
val = config.returnPoisonWindowPos()
|
||||
else:
|
||||
val = config.returnStunWindowPos()
|
||||
|
||||
self.w = val[0]
|
||||
self.h = val[1]
|
||||
self.cropped_x = val[2]
|
||||
self.cropped_y = val[3]
|
||||
|
||||
|
||||
|
||||
def get_screenshot(self):
|
||||
# get the window image data
|
||||
wDC = win32gui.GetWindowDC(self.hwnd)
|
||||
dcObj = win32ui.CreateDCFromHandle(wDC)
|
||||
cDC = dcObj.CreateCompatibleDC()
|
||||
dataBitMap = win32ui.CreateBitmap()
|
||||
dataBitMap.CreateCompatibleBitmap(dcObj, self.w, self.h)
|
||||
cDC.SelectObject(dataBitMap)
|
||||
cDC.BitBlt((0, 0), (self.w, self.h), dcObj, (self.cropped_x, self.cropped_y), win32con.SRCCOPY)
|
||||
|
||||
# convert the raw data into a format opencv can read
|
||||
#dataBitMap.SaveBitmapFile(cDC, 'debug.bmp')
|
||||
signedIntsArray = dataBitMap.GetBitmapBits(True)
|
||||
img = np.fromstring(signedIntsArray, dtype='uint8')
|
||||
img.shape = (self.h, self.w, 4)
|
||||
|
||||
# free resources
|
||||
dcObj.DeleteDC()
|
||||
cDC.DeleteDC()
|
||||
win32gui.ReleaseDC(self.hwnd, wDC)
|
||||
win32gui.DeleteObject(dataBitMap.GetHandle())
|
||||
|
||||
# drop the alpha channel, or cv.matchTemplate() will throw an error like:
|
||||
# error: (-215:Assertion failed) (depth == CV_8U || depth == CV_32F) && type == _templ.type()
|
||||
# && _img.dims() <= 2 in function 'cv::matchTemplate'
|
||||
img = img[...,:3]
|
||||
|
||||
# make image C_CONTIGUOUS to avoid errors that look like:
|
||||
# File ... in draw_rectangles
|
||||
# TypeError: an integer is required (got type tuple)
|
||||
# see the discussion here:
|
||||
# https://github.com/opencv/opencv/issues/14866#issuecomment-580207109
|
||||
img = np.ascontiguousarray(img)
|
||||
|
||||
return img
|
||||
|
||||
def get_screenshot_by_area(self, area):
|
||||
|
||||
w_local = area[0]
|
||||
h_local = area[1]
|
||||
cropped_x_local = area[2]
|
||||
cropped_y_local = area[3]
|
||||
|
||||
# get the window image data
|
||||
wDC = win32gui.GetWindowDC(self.hwnd)
|
||||
dcObj = win32ui.CreateDCFromHandle(wDC)
|
||||
cDC = dcObj.CreateCompatibleDC()
|
||||
dataBitMap = win32ui.CreateBitmap()
|
||||
dataBitMap.CreateCompatibleBitmap(dcObj, w_local, h_local)
|
||||
cDC.SelectObject(dataBitMap)
|
||||
cDC.BitBlt((0, 0), (w_local, h_local), dcObj, (cropped_x_local, cropped_y_local), win32con.SRCCOPY)
|
||||
|
||||
# convert the raw data into a format opencv can read
|
||||
#dataBitMap.SaveBitmapFile(cDC, 'debug.bmp')
|
||||
signedIntsArray = dataBitMap.GetBitmapBits(True)
|
||||
img = np.fromstring(signedIntsArray, dtype='uint8')
|
||||
img.shape = (h_local, w_local, 4)
|
||||
|
||||
# free resources
|
||||
dcObj.DeleteDC()
|
||||
cDC.DeleteDC()
|
||||
win32gui.ReleaseDC(self.hwnd, wDC)
|
||||
win32gui.DeleteObject(dataBitMap.GetHandle())
|
||||
|
||||
# drop the alpha channel, or cv.matchTemplate() will throw an error like:
|
||||
# error: (-215:Assertion failed) (depth == CV_8U || depth == CV_32F) && type == _templ.type()
|
||||
# && _img.dims() <= 2 in function 'cv::matchTemplate'
|
||||
img = img[...,:3]
|
||||
|
||||
# make image C_CONTIGUOUS to avoid errors that look like:
|
||||
# File ... in draw_rectangles
|
||||
# TypeError: an integer is required (got type tuple)
|
||||
# see the discussion here:
|
||||
# https://github.com/opencv/opencv/issues/14866#issuecomment-580207109
|
||||
img = np.ascontiguousarray(img)
|
||||
|
||||
return img
|
||||
|
||||
# find the name of the window you're interested in.
|
||||
# once you have it, update window_capture()
|
||||
# https://stackoverflow.com/questions/55547940/how-to-get-a-list-of-the-name-of-every-open-window
|
||||
@staticmethod
|
||||
def list_window_names():
|
||||
def winEnumHandler(hwnd, ctx):
|
||||
if win32gui.IsWindowVisible(hwnd):
|
||||
print(hex(hwnd), win32gui.GetWindowText(hwnd))
|
||||
win32gui.EnumWindows(winEnumHandler, None)
|
||||
|
||||
# translate a pixel position on a screenshot image to a pixel position on the screen.
|
||||
# pos = (x, y)
|
||||
# WARNING: if you move the window being captured after execution is started, this will
|
||||
# return incorrect coordinates, because the window position is only calculated in
|
||||
# the __init__ constructor.
|
||||
def get_screen_position(self, pos):
|
||||
return (pos[0] + self.offset_x, pos[1] + self.offset_y)
|
||||
Reference in New Issue
Block a user