import numpy, cv2 import win32gui, win32api, win32con, win32ui import time from PIL import Image def get_window_position(window_title): """ 获取指定窗口的左上角在桌面的位置 :param window_title: 窗口标题(支持模糊匹配) :return: (x, y) 坐标元组,未找到返回 None """ # 查找目标窗口句柄 target_hwnd = None def enum_windows_callback(hwnd, _): nonlocal target_hwnd if win32gui.IsWindowVisible(hwnd): title = win32gui.GetWindowText(hwnd) if window_title.lower() in title.lower(): # 检查是否是顶级窗口(排除子窗口) if win32gui.GetParent(hwnd) == 0: target_hwnd = hwnd return False # 停止枚举 return True # 继续枚举 # 枚举所有窗口 win32gui.EnumWindows(enum_windows_callback, None) # 获取窗口位置 if target_hwnd: rect = win32gui.GetWindowRect(target_hwnd) return rect[0], rect[1] return None, None class WindowsAPI(): def __init__(self, hwnd=None, region=None): # 如果传入 hwnd 则直接使用传入的句柄,否则设为 None self.hWnd = hwnd self.region = region # region 格式为 (left, top, right, bottom) def setRegion(self, region): """设置截图区域""" self.region = region def getDesktopImg(self): if not self.region: print("请传入有效的截图区域") return None left, top, right, bottom = self.region width = right - left height = bottom - top # 获取桌面的设备上下文句柄 hWndDC = win32gui.GetWindowDC(win32gui.GetDesktopWindow()) # 创建设备描述表 mfcDC = win32ui.CreateDCFromHandle(hWndDC) # 内存设备描述表 saveDC = mfcDC.CreateCompatibleDC() # 创建位图对象 saveBitMap = win32ui.CreateBitmap() # 分配存储空间 saveBitMap.CreateCompatibleBitmap(mfcDC, width, height) # 将位图对象选入到内存设备描述表 saveDC.SelectObject(saveBitMap) # 截取指定区域 saveDC.BitBlt((0, 0), (width, height), mfcDC, (left, top), win32con.SRCCOPY) # 获取位图信息 signedIntsArray = saveBitMap.GetBitmapBits(True) im_opencv = numpy.frombuffer(signedIntsArray, dtype='uint8') im_opencv.shape = (height, width, 4) # 内存释放 win32gui.DeleteObject(saveBitMap.GetHandle()) saveDC.DeleteDC() mfcDC.DeleteDC() win32gui.ReleaseDC(win32gui.GetDesktopWindow(), hWndDC) im_opencv = cv2.cvtColor(im_opencv, cv2.COLOR_BGR2RGB) # rgb 修改通道数并转换图像 # im_opencv=im_opencv[40:-1, 2:] im_PIL = Image.fromarray(im_opencv) # 图像改成对象类型 return [im_opencv,im_PIL] def showDesktopImg(self): imgs = self.getDesktopImg() if imgs is None: print("无法获取截图") return im_opencv = imgs[0] # 取 OpenCV 图像 cv2.imshow("Desktop Screenshot", im_opencv) cv2.waitKey(0) cv2.destroyAllWindows() # window_title = "Torchlight:Infinite" # left, top = get_window_position(window_title) # # if left is None or top is None: # print(f"错误: 未找到标题包含 '{window_title}' 的窗口") # exit(1) # # print(f"找到窗口 '{window_title}' 位置: ({left}, {top})") # 2. 设置截图区域 (左上角x, 左上角y, 右下角x, 右下角y) # width, height = 1282, 761 custom_region = (0, 30, 1280, 30+720) winApi = WindowsAPI(region=custom_region) print(winApi.region) # winApi.showDesktopImg()