18834161486 发表于 2022-3-29 20:35

图色基础功能

先将代码实例化运行一次(参数只能传一级窗口的类名),会把窗口置于左上角位置。然后用图色工具获取范围颜色等值,推荐大漠综合工具。最后面给了一个多点找色的例子
import time
import win32gui, win32ui, win32con
import ctypes
import pyautogui
import numpy as np
import copy


class GameAutoGui:
    def __init__(self, className):
      print('欢迎使用游戏自动化类库')
      self.hwnd = self.FindWin(className)
      win32gui.SetForegroundWindow(self.hwnd)
      # self.l, self.t, self.r, self.b = self.get_window_rect(self.hwnd)
      self.setWinPos(self.hwnd, 0, 0)
      # print(self.hwnd, self.l, self.t, self.r, self.b)

    def FindWin(self, des):
      return win32gui.FindWindow(des, None)

    def get_appoint_hwnd(self, hwnd: str, num: int):
      '''
      获取所有指定句柄
      :param hwnd: 类名或者窗口名字
      :param num: 0对应类名,1对应窗口名字
      :return: 数组
      '''
      hwnd_title = dict()
      li = []

      def get_all_hwnd(hwnd, mouse):
            if win32gui.IsWindow(hwnd) and win32gui.IsWindowEnabled(hwnd) and win32gui.IsWindowVisible(hwnd):
                if num:
                  hwnd_title.update({hwnd: win32gui.GetWindowText(hwnd)})
                else:
                  hwnd_title.update({hwnd: win32gui.GetClassName(hwnd)})

      win32gui.EnumWindows(get_all_hwnd, 0)
      for h, t in hwnd_title.items():
            if str(t) == hwnd:
                # print(h, t)
                li.append(h)
      return li

    def get_window_rect(self, hwnd):
      '''
      获取窗口坐标
      :param hwnd: 句柄所在指针
      :return: 元组(rect.left, rect.top, rect.right, rect.bottom)
      '''
      import ctypes.wintypes
      try:
            f = ctypes.windll.dwmapi.DwmGetWindowAttribute
      except WindowsError:
            f = None
      if f:
            rect = ctypes.wintypes.RECT()
            DWMWA_EXTENDED_FRAME_BOUNDS = 9
            f(ctypes.wintypes.HWND(hwnd),
            ctypes.wintypes.DWORD(DWMWA_EXTENDED_FRAME_BOUNDS),
            ctypes.byref(rect),
            ctypes.sizeof(rect)
            )
            return rect.left, rect.top, rect.right, rect.bottom

    def click(self, x, y):
      x = int(x)
      y = int(y)
      ctypes.windll.user32.SetCursorPos(x, y)
      ctypes.windll.user32.mouse_event(2, 0, 0, 0, 0)
      time.sleep(0.1)
      ctypes.windll.user32.mouse_event(4, 0, 0, 0, 0)

    def setWinPos(self, hwnd, x, y):
      '''
      设置窗口位置
      :param hwnd: 句柄
      :param x: X坐标
      :param y: Y坐标
      :return:
      '''
      return ctypes.windll.user32.SetWindowPos(hwnd, 0, x, y, 0, 0, 0X0001 | 0X0004)

    #截图
    def getCapture(self, stax, stay, endx, endy):
      w = endx - stax
      h = endy - stay
      # print(stax, stay, endx, endy,w,h)
      im = pyautogui.screenshot(region=(stax, stay, w, h))
      im.save("123.bmp")

    # 定点比色
    def cmpcolor(self, x, y, color):
      # print(x, y)
      color = self.Hex_to_RGB2(color)
      im = pyautogui.screenshot(region=(0, 0, x + 10, y + 10))
      res = im.getpixel((x, y))
      # print(res)
      if res == color and res == color and res == color:
            return True
      else:
            return False

    def RGB_to_Hex(self, rgb):
      RGB = rgb.split(',')# 将RGB格式划分开来
      color = '#'
      for i in RGB:
            num = int(i)
            # 将R、G、B分别转化为16进制拼接转换并大写hex() 函数用于将10进制整数转换成16进制,以字符串形式表示
            color += str(hex(num))[-2:].replace('x', '0').upper()
      print(color)
      return color

    def Hex_to_RGB(self, hex):
      r = int(hex, 16)
      g = int(hex, 16)
      b = int(hex, 16)
      return b, g, r

    def Hex_to_RGB2(self, hex):
      r = int(hex, 16)
      g = int(hex, 16)
      b = int(hex, 16)
      return r, g, b

    #获取颜色数量
    def getcolornum(self, stax: int, stay: int, endx: int, endy: int, des):
      w = endx - stax
      h = endy - stay
      im = pyautogui.screenshot(region=(stax, stay, w, h))
      im = np.array(im)
      # print(im)
      des = list(self.Hex_to_RGB2(des))
      # print(des)
      result = np.count_nonzero(np.all(im == des, axis=2))
      print(result)
      return result

    #找色
    def FindColor(self, stax: int, stay: int, endx: int, endy: int, des):
      w = endx - stax
      h = endy - stay
      im = pyautogui.screenshot(region=(stax, stay, w, h))
      im = np.array(im)
      des = list(self.Hex_to_RGB2(des))
      result = np.argwhere(np.all(im == des, axis=2)).tolist()
      print(result)
      for i in result:
            a = i
            i = stax + i
            i = stay + a
      # print(result)
      return result

    # 多点找色
    def FindFindColor(self, stax: int, stay: int, endx: int, endy: int, des):
      w = endx - stax
      h = endy - stay
      im = pyautogui.screenshot(region=(stax, stay, w, h))
      im = np.array(im)
      global headCoordinate, matched, corrdinate
      corrdinate = np.empty()
      for i in des:
            if type(i) == str:
                # print('我是头部', i)
                headColor = self.Hex_to_RGB2(i)
                # print('头部颜色', headColor)
                headCoordinate = np.argwhere(np.all(im == headColor, axis=2))
                # print('头部坐标', headCoordinate)
            else:
                # print('我是身体', i)
                bodyColor = self.Hex_to_RGB2(i)
                # print('身体颜色', bodyColor)
                bodyCoordinate = np.argwhere(np.all(im == bodyColor, axis=2))
                # print('身体坐标', bodyCoordinate)
                headBodyCoordinate = copy.deepcopy(headCoordinate)
                for index in headBodyCoordinate:
                  index = int(index) + i
                  index = int(index) + i
                # print('头部坐标', headCoordinate)
                # print('头部偏移后坐标', headBodyCoordinate)
                q = set()
                w = set()
                matched = np.array(list(q.intersection(w)))
                # print('相同坐标', matched)
                beforeMatched = copy.deepcopy(matched)
                for index in beforeMatched:
                  index = int(index) - i
                  index = int(index) - i
                # print('相同坐标的原坐标', beforeMatched)
                corrdinate = np.append(corrdinate, beforeMatched, axis=0)
                # print('中间结果', corrdinate)
      # print('结果', corrdinate)
      corrdinate = corrdinate.tolist()
      for i in corrdinate:
            # print(corrdinate.count(i))
            if corrdinate.count(i) == len(des) - 1:
                return i + stax, i + stay
      return -1,-1


# a = GameAutoGui('LDPlayerMainFrame')
# b = a.FindFindColor(20,361,117,467,
#                     ['#a3906f', , , , ])
# print(b)

daimmon 发表于 2022-3-30 07:47

import pyautogui
import time
import xlrd
import pyperclip

#定义鼠标事件

#pyautogui库其他用法 https://blog.csdn.net/qingfengxd1/article/details/108270159

def mouseClick(clickTimes,lOrR,img,reTry):
    if reTry == 1:
      while True:
            location=pyautogui.locateCenterOnScreen(img,confidence=0.9)
            if location is not None:
                pyautogui.click(location.x,location.y,clicks=clickTimes,interval=0.2,duration=0.2,button=lOrR)
                break
            print("未找到匹配图片,0.1秒后重试")
            time.sleep(0.1)
    elif reTry == -1:
      while True:
            location=pyautogui.locateCenterOnScreen(img,confidence=0.9)
            if location is not None:
                pyautogui.click(location.x,location.y,clicks=clickTimes,interval=0.2,duration=0.2,button=lOrR)
            time.sleep(0.1)
    elif reTry > 1:
      i = 1
      while i < reTry + 1:
            location=pyautogui.locateCenterOnScreen(img,confidence=0.9)
            if location is not None:
                pyautogui.click(location.x,location.y,clicks=clickTimes,interval=0.2,duration=0.2,button=lOrR)
                print("重复")
                i += 1
            time.sleep(0.1)




# 数据检查
# cmdType.value1.0 左键单击    2.0 左键双击3.0 右键单击4.0 输入5.0 等待6.0 滚轮
# ctype   空:0
#         字符串:1
#         数字:2
#         日期:3
#         布尔:4
#         error:5
def dataCheck(sheet1):
    checkCmd = True
    #行数检查
    if sheet1.nrows<2:
      print("没数据啊哥")
      checkCmd = False
    #每行数据检查
    i = 1
    while i < sheet1.nrows:
      # 第1列 操作类型检查
      cmdType = sheet1.row(i)
      if cmdType.ctype != 2 or (cmdType.value != 1.0 and cmdType.value != 2.0 and cmdType.value != 3.0
      and cmdType.value != 4.0 and cmdType.value != 5.0 and cmdType.value != 6.0):
            print('第',i+1,"行,第1列数据有毛病")
            checkCmd = False
      # 第2列 内容检查
      cmdValue = sheet1.row(i)
      # 读图点击类型指令,内容必须为字符串类型
      if cmdType.value ==1.0 or cmdType.value == 2.0 or cmdType.value == 3.0:
            if cmdValue.ctype != 1:
                print('第',i+1,"行,第2列数据有毛病")
                checkCmd = False
      # 输入类型,内容不能为空
      if cmdType.value == 4.0:
            if cmdValue.ctype == 0:
                print('第',i+1,"行,第2列数据有毛病")
                checkCmd = False
      # 等待类型,内容必须为数字
      if cmdType.value == 5.0:
            if cmdValue.ctype != 2:
                print('第',i+1,"行,第2列数据有毛病")
                checkCmd = False
      # 滚轮事件,内容必须为数字
      if cmdType.value == 6.0:
            if cmdValue.ctype != 2:
                print('第',i+1,"行,第2列数据有毛病")
                checkCmd = False
      i += 1
    return checkCmd

#任务
def mainWork(img):
    i = 1
    while i < sheet1.nrows:
      #取本行指令的操作类型
      cmdType = sheet1.row(i)
      if cmdType.value == 1.0:
            #取图片名称
            img = sheet1.row(i).value
            reTry = 1
            if sheet1.row(i).ctype == 2 and sheet1.row(i).value != 0:
                reTry = sheet1.row(i).value
            mouseClick(1,"left",img,reTry)
            print("单击左键",img)
      #2代表双击左键
      elif cmdType.value == 2.0:
            #取图片名称
            img = sheet1.row(i).value
            #取重试次数
            reTry = 1
            if sheet1.row(i).ctype == 2 and sheet1.row(i).value != 0:
                reTry = sheet1.row(i).value
            mouseClick(2,"left",img,reTry)
            print("双击左键",img)
      #3代表右键
      elif cmdType.value == 3.0:
            #取图片名称
            img = sheet1.row(i).value
            #取重试次数
            reTry = 1
            if sheet1.row(i).ctype == 2 and sheet1.row(i).value != 0:
                reTry = sheet1.row(i).value
            mouseClick(1,"right",img,reTry)
            print("右键",img)
      #4代表输入
      elif cmdType.value == 4.0:
            inputValue = sheet1.row(i).value
            pyperclip.copy(inputValue)
            pyautogui.hotkey('ctrl','v')
            time.sleep(0.5)
            print("输入:",inputValue)                                       
      #5代表等待
      elif cmdType.value == 5.0:
            #取图片名称
            waitTime = sheet1.row(i).value
            time.sleep(waitTime)
            print("等待",waitTime,"秒")
      #6代表滚轮
      elif cmdType.value == 6.0:
            #取图片名称
            scroll = sheet1.row(i).value
            pyautogui.scroll(int(scroll))
            print("滚轮滑动",int(scroll),"距离")                     
      i += 1

if __name__ == '__main__':
    file = 'cmd.xls'
    #打开文件
    wb = xlrd.open_workbook(filename=file)
    #通过索引获取表格sheet页
    sheet1 = wb.sheet_by_index(0)
    print('欢迎使用不高兴就喝水牌RPA~')
    #数据检查
    checkCmd = dataCheck(sheet1)
    if checkCmd:
      key=input('选择功能: 1.做一次 2.循环到死 \n')
      if key=='1':
            #循环拿出每一行指令
            mainWork(sheet1)
      elif key=='2':
            while True:
                mainWork(sheet1)
                time.sleep(0.1)
                print("等待0.1秒")   
    else:
      print('输入有误或者已经退出!')

请叫我老龚 发表于 2022-3-30 16:26

页: [1]
查看完整版本: 图色基础功能