可以稳刷的单机版本
This commit is contained in:
115
utils/WindowsAPI.py
Normal file
115
utils/WindowsAPI.py
Normal file
@@ -0,0 +1,115 @@
|
||||
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()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user