python基于win32实现梦幻西游手游后台鼠标键盘

# 需要安装pywin32,numpy,cv2模块

import time
import win32api
import win32con
import win32gui
import win32ui
import numpy
import cv2


class Util(object):
    def __init__(self, hwnd) -> None:
        self.hwnd = hwnd

    def capture_screen(self):
        try:
            left, top, right, bot = win32gui.GetWindowRect(self.hwnd)
            width = right - left
            height = bot - top
            # 返回句柄窗口的设备环境,覆盖整个窗口,包括非客户区,标题栏,菜单,边框
            while self.hwnd == 0:
                print('hwnd==0')
                return
            hWndDC = win32gui.GetWindowDC(self.hwnd)
            # 创建设备描述表
            mfcDC = win32ui.CreateDCFromHandle(hWndDC)
            # 创建内存设备描述表
            saveDC = mfcDC.CreateCompatibleDC()
            # 创建位图对象准备保存图片
            saveBitMap = win32ui.CreateBitmap()
            # 为bitmap开辟存储空间
            saveBitMap.CreateCompatibleBitmap(mfcDC, width, height)
            # 将截图保存到saveBitMap中
            saveDC.SelectObject(saveBitMap)
            # 保存bitmap到内存设备描述表
            saveDC.BitBlt((0, 0), (width, height), mfcDC, (0, 0), win32con.SRCCOPY)

            # 方法三(第一部分):opencv+numpy保存
            # 获取位图信息
            signedIntsArray = saveBitMap.GetBitmapBits(True)

            # 方法三(第二部分):opencv+numpy保存
            # PrintWindow成功,保存到文件,显示到屏幕

            im_opencv = numpy.frombuffer(signedIntsArray, dtype='uint8')
            im_opencv.shape = (height, width, 4)
            cv2.cvtColor(im_opencv, cv2.COLOR_BGRA2RGB)
            cv2.imencode(".bmp", im_opencv)[1].tofile('截图'+str(self.hwnd)+'.bmp')

            # 内存释放
            win32gui.DeleteObject(saveBitMap.GetHandle())
            saveDC.DeleteDC()
            mfcDC.DeleteDC()
            win32gui.ReleaseDC(self.hwnd, hWndDC)
            # cv2.namedWindow('im_opencv') #命名窗口
            # cv2.imshow("im_opencv",im_opencv) #显示
            # cv2.waitKey(0)
            # cv2.destroyAllWindows()
            # 方法一
            # saveBitMap.SaveBitmapFile(saveDC,"img_Winapi.bmp")
            return
        except :
            print('异常')
    def get_hwnd(title):
        hwnd = win32gui.FindWindow(0, title)
        return hwnd

    def get_son_hwnd(parent):
        if not parent:
            return
        son_hwnd = []
        win32gui.EnumChildWindows(
            parent, lambda hwnd, param: param.append(hwnd), son_hwnd)
        print('son_hwnd:', son_hwnd)
        return son_hwnd[0]

    def get_window_hwnd():

        return win32gui.GetDesktopWindow()

    def click(self, x, y):
        posi = win32api.MAKELONG(int(x), int(y))
        win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONDOWN,
                             win32con.MK_LBUTTON, posi)

        win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONUP,
                             win32con.MK_LBUTTON, posi)

    
    def swipe(self, template, similarity, numb1: int, numb2: int):
        while True:
            time.sleep(3)
            self.capture_screen()
            tmp = self.match_template(template, similarity)

            if max(numb2, numb1) > len(tmp[1]):
                continue
            else:
                posi = win32api.MAKELONG(
                    int(tmp[1][numb1][0]), int(tmp[1][numb1][1]))
                posi2 = win32api.MAKELONG(
                    int(tmp[1][numb2][0]), int(tmp[1][numb2][1]))
                win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONDOWN,
                                     win32con.MK_LBUTTON, posi)

                win32api.SendMessage(self.hwnd, win32con.WM_MOUSEMOVE, 0, 0)
                win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONUP,
                                     win32con.MK_LBUTTON, posi2)
                time.sleep(5)
                self.capture_screen()
                return

    def find_and_click(self, template, similarity):
        while True:
            if self.find_image(template, similarity)[0] is True:
                posi = self.find_image(template, similarity)
                self.click(posi[1][0], posi[1][1])
                time.sleep(3)
                self.capture_screen()
                if self.find_image(template, similarity)[0] is True:
                    self.find_and_click(template, similarity)
                    return posi
                else:
                    return posi
            time.sleep(10)
            self.capture_screen()

    def find_click_once(self, template, similarity):
        while True:
            if self.find_image(template, similarity)[0] is True:
                posi = self.find_image(template, similarity)
                self.click(posi[1][0], posi[1][1])
                return posi
            self.capture_screen()

    def find_two_click(self, template1, template2, similarity):
        while True:
            self.capture_screen()
            t = self.find_image(template1, similarity)
            if t[0] is True:
                tmp = self.match_template(template2, similarity)
                min = 1000
                x = 0
                y = 0
                for i in tmp[1]:
                    if abs(i[1]-t[1][1]) < min:
                        min = abs(i[1]-t[1][1])
                        x = i[0]
                        y = i[1]
                self.click(x, y)
                print(x, y)
                return (x, y)

    def find_all_and_click(self, template, similarity, numb):
        while True:
            tmp = self.match_template(template, similarity)
            if tmp[0] is True:
                if len(tmp[1]) > numb:
                    self.click(tmp[1][numb][0], tmp[1][numb][1])
                    print(tmp)
                    return tmp
            self.capture_screen()

    # TM_CCOEFF相关系数匹配
    # TM_CCOEFF_NORMED归一化相关系数匹配
    # TM_CCORR相关匹配.模板图像相乘,数值大最佳匹配,数值小最差匹配
    # TM_CCORR_NORMED归一化相关匹配
    # TM_SQDIFF平方差匹配.最佳匹配=0
    # TM_SQDIFF_NORMED标准平方差匹配

    def find_image(self, template: str, similarity: float):
        try:
            scr = cv2.imdecode(numpy.fromfile(
                '截图'+str(self.hwnd)+'.bmp', dtype=numpy.uint8), 0)
            tp = cv2.imdecode(numpy.fromfile(template, dtype=numpy.uint8), 0)
            result = cv2.matchTemplate(scr, tp, cv2.TM_CCOEFF_NORMED)
        except cv2.error:
            print('file error')
            return False, None
        h, w = tp.shape[:2]
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)

        if max_val < similarity:
            return False, None
        else:
            posi = (max_loc[0]+w//2, max_loc[1]+h//2,
                    max_loc[0], max_loc[1]-h, max_loc[0]+w, max_loc[1]-h)
            return True, posi

    def match_template(self, template: str, similarity: float):
        try:
            scr = cv2.imdecode(numpy.fromfile(
                '截图'+str(self.hwnd)+'.bmp', dtype=numpy.uint8), 0)
            tp = cv2.imdecode(numpy.fromfile(template, dtype=numpy.uint8), 0)
        except cv2.error:
            print('file err')
        posi = []
        h, w = tp.shape[:2]
        match = cv2.matchTemplate(scr, tp, cv2.TM_CCOEFF_NORMED)
        indices = (-match).argpartition(100, axis=None)[:100]
        unreveled_indices = numpy.array(
            numpy.unravel_index(indices, match.shape)).T
        for location in unreveled_indices:
            y, x = location
            confidence = match[y][x]
            if confidence >= similarity:
                posi.append((x+w//2, y+h//2))
        tmp = []  # 接收posi坐标
        for i in range(len(posi)-1):
            for j in range(i+1, len(posi)):
                if abs(posi[i][0]-posi[j][0]) <= 3 and abs(posi[i][1]-posi[j][1]) <= 3:
                    tmp.append(j)
        for i in reversed(list(set(tmp))):
            posi.pop(i)
        posi.sort(key=lambda x: x[1])
        return True, posi
  1. 获取窗口句柄

        可以使用按键精灵的按键抓抓

        

def get_child_windows(parent):        
    '''     
    获得parent的所有子窗口句柄
     返回子窗口句柄列表
     '''     
    if not parent:         
        return      
    hwndChildList = []     
    win32gui.EnumChildWindows(parent, lambda hwnd, param: param.append(hwnd),  hwndChildList)          
    return hwndChildList 

你可能感兴趣的:(python,opencv,开发语言)