import sys import win32gui from PyQt5.QtWidgets import QApplication import numpy import cv2 from pathlib import Path from ctypes import windll, byref from ctypes.wintypes import HWND, POINT import time
zjb = [] hld = win32gui.FindWindow(None, u"BlueStacks App Player") print('主窗口ID', hld) win32gui.EnumChildWindows(hld, lambda aa, bb: bb.append(aa), zjb) print('子窗口ID', zjb) print(zjb[1])
通过句柄获取窗口的左、上、右、下,位置
left, top, right, bottom = win32gui.GetWindowRect(zjb[1]) print(left, top, right, bottom)
----------------------------------------------------------后台鼠标键盘操作
PostMessageW = windll.user32.PostMessageW ClientToScreen = windll.user32.ClientToScreen WM_MOUSEMOVE = 0x0200 WM_LBUTTONDOWN = 0x0201 WM_LBUTTONUP = 0x202 WM_MOUSEWHEEL = 0x020A WHEEL_DELTA = 120
def move_to(handle: HWND, x: int, y: int): """移动鼠标到坐标(x, y)
Args:
    handle (HWND): 窗口句柄
    x (int): 横坐标
    y (int): 纵坐标
"""
# https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-mousemove
wparam = 0
lparam = y << 16 | x
PostMessageW(handle, WM_MOUSEMOVE, wparam, lparam)def left_down(handle: HWND, x: int, y: int): """在坐标(x, y)按下鼠标左键
Args:
    handle (HWND): 窗口句柄
    x (int): 横坐标
    y (int): 纵坐标
"""
# https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-lbuttondown
wparam = 0
lparam = y << 16 | x
PostMessageW(int(handle), int(WM_LBUTTONDOWN), int(wparam), int(lparam))def left_up(handle: HWND, x: int, y: int): """在坐标(x, y)放开鼠标左键
Args:
    handle (HWND): 窗口句柄
    x (int): 横坐标
    y (int): 纵坐标
"""
# https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-lbuttonup
wparam = 0
lparam = y << 16 | x
PostMessageW(int(handle), int(WM_LBUTTONUP), int(wparam), int(lparam))-------------------------------------------区域找图,识别截图并返回坐标
class Image: def init(self, image): self.image = cv2.imread(image, cv2.IMREAD_UNCHANGED)
@property
def width(self):
    return self.image.shape[1]
@property
def height(self):
    return self.image.shape[0]class MatchImg(object): def init(self, source, template, threshod=0.95): """ 匹配一个图片,是否是另一个图片的局部图。source是大图,template是小图。即判断小图是否是大图的一部分。 :param source: :param template: :param threshod: 匹配程度,值越大,匹配程度要求就越高,最好不要太小 """ self.source_img = source self.template_img = template self.threshod = threshod
def match_template(self, method=cv2.TM_CCOEFF_NORMED):
    """
    返回小图左上角的点,在大图中的坐标。
    :param method:
    :return: list[tuple(x,y),...]
    """
    try:
        result = cv2.matchTemplate(self.source_img.image, self.template_img.image, method)
        locations = numpy.where(result >= self.threshod)
        res = list(zip(locations[1], locations[0]))  # 返回的是匹配到的template左上角那个坐标点在image中的位置,可能有多个值
        return res
    except cv2.error as e:
        print(e)
def get_template_position(self):
    """
    获取小图在大图中,左上角和右下角的坐标
    :return: List[list[x,y,x,y],...]
    """
    res = self.match_template()
    new_pos = []
    for r in res:
        r = list(r)
        r.append(r[0]+self.template_img.width)
        r.append(r[1]+self.template_img.height)
        new_pos.append(r)
    return new_pos
def get_img_center(self):
    """
    获取大图中,每个小图中心点所在的坐标
    :return:
    """
    pos = self.match_template()
    points = []
    for p in pos:
        x, y = p[0]+int(self.template_img.width/2), p[1]+int(self.template_img.height/2)
        points.append((x, y))
    return pointsdef load_image_file(path): path = Path(path) if not path.exists(): print('not exist file') try: image = Image(str(path)) return image except cv2.error as e: print(e)
pyautogui.PAUSE = 1
im = pyautogui.screenshot() # 前台全屏截图
可把窗口遮挡截图并保存
#----------------------------------------------------以下为登录和角色选择------------------------------------------------
def jbdy(canshu): # 自定义类时,需要引号
app = QApplication(sys.argv) screen = QApplication.primaryScreen() xhcs = 0 while xhcs<4: for canshu in range(1, 7): # 此处1-7可以登陆6个账号重复循环 img = screen.grabWindow(hld).toImage() img.save(r'D:\findpic\jt.bmp') time.sleep(2) img1 = load_image_file(r'D:\findpic\jt.bmp') img2 = load_image_file(r'D:\findpic\dl.bmp') process = MatchImg(img1, img2, 0.9) points = process.get_img_center() if points==[]: ii = 0 while points==[]: # 如果返回的坐标为空,继续循环查找 img = screen.grabWindow(hld).toImage() img.save(r'D:\findpic\jt.bmp') time.sleep(2) img1 = load_image_file(r'D:\findpic\jt.bmp') img2 = load_image_file(r'D:\findpic\dl.bmp') process = MatchImg(img1, img2, 0.9) points = process.get_img_center() ii+=1 if ii>100: print('没有') exit() # exit()和quit()都是直接退出程序 # points1 = process.get_template_position() # print(points1) # 找到图的左上角和右下角的坐标 print(points, '登录') # 找到图的中心点坐标 print(points[0][0], points[0][1]) left_down(zjb[1], points[0][0], points[0][1]-40) # 此处我们按下的点是:横坐标为返回中心横坐标+i,纵坐标为返回中心坐标的纵坐标 time.sleep(0.1) left_up(zjb[1], points[0][0], points[0][1]-40) # 此处我们弹起的点是:横坐标为返回中心横坐标+i,纵坐标为返回中心坐标的纵坐标 time.sleep(3) # 不知道为什么要减40,但是减去40就可以正确点击 img = screen.grabWindow(hld).toImage() img.save(r'D:\findpic\jt.bmp') time.sleep(2) img1 = load_image_file(r'D:\findpic\jt.bmp') img2 = load_image_file(r'D:\findpic\fwq.bmp') process = MatchImg(img1, img2, 0.9) points = process.get_img_center() if points==[]: ii = 0 while points==[]: # 如果返回的坐标为空,继续循环查找 img = screen.grabWindow(hld).toImage() img.save(r'D:\findpic\jt.bmp') time.sleep(2) img1 = load_image_file(r'D:\findpic\jt.bmp') img2 = load_image_file(r'D:\findpic\fwq.bmp') process = MatchImg(img1, img2, 0.9) points = process.get_img_center() ii+=1 if ii>100: print('没有') exit() # exit()和quit()都是直接退出程序 # points1 = process.get_template_position() # print(points1) # 找到图的左上角和右下角的坐标 print(points, '选择服务器') # 找到图的中心点坐标 print(points[0][0], points[0][1]) left_down(zjb[1], points[0][0], points[0][1]-40) # 此处我们按下的点是:横坐标为返回中心横坐标+i,纵坐标为返回中心坐标的纵坐标 time.sleep(0.1) left_up(zjb[1], points[0][0], points[0][1]-40) # 此处我们弹起的点是:横坐标为返回中心横坐标+i,纵坐标为返回中心坐标的纵坐标 time.sleep(10) img = screen.grabWindow(hld).toImage() img.save(r'D:\findpic\jt.bmp') time.sleep(2) img1 = load_image_file(r'D:\findpic\jt.bmp') img2 = load_image_file(r'D:\findpic\js'+str(canshu)+'.bmp') # 路径字符中有变量的写法。6个角色的选择,给角色图片编上号 process = MatchImg(img1, img2, 0.9) points = process.get_img_center() if points==[]: ii = 0 while points==[]: # 如果返回的坐标为空,继续循环查找 img = screen.grabWindow(hld).toImage() img.save(r'D:\findpic\jt.bmp') time.sleep(2) img1 = load_image_file(r'D:\findpic\jt.bmp') img2 = load_image_file(r'D:\findpic\js'+str(canshu)+'1.bmp') # 路径字符中有变量的写法 process = MatchImg(img1, img2, 0.9) points = process.get_img_center() ii+=1 if ii>100: print('没有') exit() # exit()和quit()都是直接退出程序 # points1 = process.get_template_position() # print(points1) # 找到图的左上角和右下角的坐标 print(points, '选择角色') # 找到图的中心点坐标 print(points[0][0], points[0][1]) left_down(zjb[1], points[0][0], points[0][1]-40) # 此处我们按下的点是:横坐标为返回中心横坐标+i,纵坐标为返回中心坐标的纵坐标 time.sleep(0.1) left_up(zjb[1], points[0][0], points[0][1]-40) # 此处我们弹起的点是:横坐标为返回中心横坐标+i,纵坐标为返回中心坐标的纵坐标 time.sleep(6) #-------------------------------------------以上为登录和角色选择-------------------------------------------------------- #-----------------------------------------------以下为运镖任务--------------------------------------------- img = screen.grabWindow(hld).toImage() img.save(r'D:\findpic\jietu.bmp') time.sleep(2) img1 = load_image_file(r'D:\findpic\jietu.bmp') img2 = load_image_file(r'D:\findpic\hd.bmp') process = MatchImg(img1, img2, 0.9) points = process.get_img_center() if points==[]: ii = 0 while points==[]: # 如果返回的坐标为空,继续循环查找 img = screen.grabWindow(hld).toImage() img.save(r'D:\findpic\jietu.bmp') time.sleep(2) img1 = load_image_file(r'D:\findpic\jietu.bmp') img2 = load_image_file(r'D:\findpic\hd.bmp') process = MatchImg(img1, img2, 0.9) points = process.get_img_center() ii+=1 if ii>100: print('没有') exit() # exit()和quit()都是直接退出程序
    print(points, '点活动--运镖')  # 找到图的中心点坐标
    points1 = process.get_template_position()
    print(points1)  # 找到图的左上角和右下角的坐标
    print(points[0][0], points[0][1])
    left_down(zjb[1], points[0][0], points[0][1]-40)  # 此处我们按下的点是:横坐标为返回中心横坐标+i,纵坐标为返回中心坐标的纵坐标
    time.sleep(0.1)
    left_up(zjb[1], points[0][0], points[0][1]-40)   # 此处我们弹起的点是:横坐标为返回中心横坐标+i,纵坐标为返回中心坐标的纵坐标
    time.sleep(3)
    img = screen.grabWindow(hld).toImage()
    img.save(r'D:\findpic\jietu.bmp')
    time.sleep(2)
    img1 = load_image_file(r'D:\findpic\jietu.bmp')
    img2 = load_image_file(r'D:\findpic\ybrw.bmp')
    process = MatchImg(img1, img2, 0.9)
    points = process.get_img_center()
    if points==[]:
        ii = 0
        while points==[]:  #  如果返回的坐标为空,继续循环查找
            img = screen.grabWindow(hld).toImage()
            img.save(r'D:\findpic\jietu.bmp')
            time.sleep(2)
            img1 = load_image_file(r'D:\findpic\jietu.bmp')
            img2 = load_image_file(r'D:\findpic\ybrw.bmp')
            process = MatchImg(img1, img2, 0.90)
            points = process.get_img_center()
            ii+=1
            print('重试' + str(ii))
            if ii>100:
                print('没有')
                exit()  # exit()和quit()都是直接退出程序
    print(points)  # 找到图的中心点坐标
    points1 = process.get_template_position()
    print(points1, '点击运镖')  # 找到图的左上角和右下角的坐标
    #---------------------------------------------------------------------
    i=120
    j=35 # 不知道为什么坐标位置,始终有点差别
    print(points1[0][2])
    print(points1[0][3])
    left_down(zjb[1], points1[0][2]+i, points1[0][3]-j)  # 此处我们按下的点是:横坐标为返回右下角横坐标,纵坐标为返回右下角纵坐标-j
    time.sleep(0.1)
    left_up(zjb[1], points1[0][2]+i, points1[0][3]-j)   # 此处我们弹起的点是:横坐标为返回右下角横坐标,纵坐标为返回右下角纵坐标-j
    time.sleep(2)
    #----------------------------------------------------------------------
    img = screen.grabWindow(hld).toImage()
    img.save(r'D:\findpic\jietu.bmp')
    time.sleep(3)
    img1 = load_image_file(r'D:\findpic\jietu.bmp')
    img2 = load_image_file(r'D:\findpic\ybrw-1.bmp')
    process = MatchImg(img1, img2, 0.9)
    points = process.get_img_center()
    if points==[]:
        ii = 0
        while points==[]:  #  如果返回的坐标为空,继续循环查找
            img = screen.grabWindow(hld).toImage()
            img.save(r'D:\findpic\jietu.bmp')
            time.sleep(2)
            img1 = load_image_file(r'D:\findpic\jietu.bmp')
            img2 = load_image_file(r'D:\findpic\ybrw-1.bmp')
            process = MatchImg(img1, img2, 0.9)
            points = process.get_img_center()
            ii+=1
            print('重试' + str(ii))
            if ii>100:
                print('没有')
                exit()  # exit()和quit()都是直接退出程序
    print(points, '接收运镖任务')  # 找到图的中心点坐标
    points1 = process.get_template_position()
    print(points1)  # 找到图的左上角和右下角的坐标
    left_down(zjb[1], points[0][0], points[0][1]-40)  # 此处我们按下的点是:横坐标为返回中心横坐标+i,纵坐标为返回中心坐标的纵坐标
    time.sleep(0.1)
    left_up(zjb[1], points[0][0], points[0][1]-40)   # 此处我们弹起的点是:横坐标为返回中心横坐标+i,纵坐标为返回中心坐标的纵坐标
    time.sleep(3)
    img = screen.grabWindow(hld).toImage()
    img.save(r'D:\findpic\jietu.bmp')
    time.sleep(3)
    img1 = load_image_file(r'D:\findpic\jietu.bmp')
    img2 = load_image_file(r'D:\findpic\ybrw-2.bmp')
    process = MatchImg(img1, img2, 0.9)
    points = process.get_img_center()
    if points==[]:
        ii = 0
        while points==[]:  #  如果返回的坐标为空,继续循环查找
            img = screen.grabWindow(hld).toImage()
            img.save(r'D:\findpic\jietu.bmp')
            time.sleep(2)
            img1 = load_image_file(r'D:\findpic\jietu.bmp')
            img2 = load_image_file(r'D:\findpic\ybrw-2.bmp')
            process = MatchImg(img1, img2, 0.9)
            points = process.get_img_center()
            ii+=1
            print('重试' + str(ii))
            if ii>100:
                print('没有')
                exit()  # exit()和quit()都是直接退出程序
    print(points, '开始运镖')  # 找到图的中心点坐标
    points1 = process.get_template_position()
    print(points1)  # 找到图的左上角和右下角的坐标
    left_down(zjb[1], points[0][0], points[0][1]-40)  # 此处我们按下的点是:横坐标为返回中心横坐标+i,纵坐标为返回中心坐标的纵坐标
    time.sleep(0.1)
    left_up(zjb[1], points[0][0], points[0][1]-40)   # 此处我们弹起的点是:横坐标为返回中心横坐标+i,纵坐标为返回中心坐标的纵坐标
    time.sleep(3)
    img1 = load_image_file(r'D:\findpic\jietu.bmp')
    img2 = load_image_file(r'D:\findpic\mjxy-tc1.bmp')
    process = MatchImg(img1, img2, 0.9)
    points = process.get_img_center()
    if points == []:
        ii = 0
        while points == []:  # 如果返回的坐标为空,继续循环查找
            img = screen.grabWindow(hld).toImage()
            img.save(r'D:\findpic\jietu.bmp')
            time.sleep(2)
            img1 = load_image_file(r'D:\findpic\jietu.bmp')
            img2 = load_image_file(r'D:\findpic\mjxy-tc1.bmp')
            process = MatchImg(img1, img2, 0.9)
            points = process.get_img_center()
            ii += 1
            print('重试' + str(ii))
            if ii > 100:
                print('没有')
                exit()  # exit()和quit()都是直接退出程序
    print(points, '左上角点击打开隐藏按钮')  # 找到图的中心点坐标
    points1 = process.get_template_position()
    print(points1)  # 找到图的左上角和右下角的坐标
    left_down(zjb[1], points[0][0], points[0][1] - 40)  # 此处我们按下的点是:横坐标为返回中心横坐标+i,纵坐标为返回中心坐标的纵坐标
    time.sleep(0.1)
    left_up(zjb[1], points[0][0], points[0][1] - 40)  # 此处我们弹起的点是:横坐标为返回中心横坐标+i,纵坐标为返回中心坐标的纵坐标
    time.sleep(2)
    img = screen.grabWindow(hld).toImage()
    img.save(r'D:\findpic\jietu.bmp')
    time.sleep(3)
    img1 = load_image_file(r'D:\findpic\jietu.bmp')
    img2 = load_image_file(r'D:\findpic\mjxy-tc2.bmp')
    process = MatchImg(img1, img2, 0.9)
    points = process.get_img_center()
    if points == []:
        ii = 0
        while points == []:  # 如果返回的坐标为空,继续循环查找
            img = screen.grabWindow(hld).toImage()
            img.save(r'D:\findpic\jietu.bmp')
            time.sleep(2)
            img1 = load_image_file(r'D:\findpic\jietu.bmp')
            img2 = load_image_file(r'D:\findpic\mjxy-tc2.bmp')
            process = MatchImg(img1, img2, 0.9)
            points = process.get_img_center()
            ii += 1
            print('重试' + str(ii))
            if ii > 100:
                print('没有')
                exit()  # exit()和quit()都是直接退出程序
    print(points, '点击系统')  # 找到图的中心点坐标
    points1 = process.get_template_position()
    print(points1)  # 找到图的左上角和右下角的坐标
    left_down(zjb[1], points[0][0], points[0][1] - 40)  # 此处我们按下的点是:横坐标为返回中心横坐标+i,纵坐标为返回中心坐标的纵坐标
    time.sleep(0.1)
    left_up(zjb[1], points[0][0], points[0][1] - 40)  # 此处我们弹起的点是:横坐标为返回中心横坐标+i,纵坐标为返回中心坐标的纵坐标
    time.sleep(2)
    img1 = load_image_file(r'D:\findpic\jietu.bmp')
    img2 = load_image_file(r'D:\findpic\qhzh.bmp')
    process = MatchImg(img1, img2, 0.9)
    points = process.get_img_center()
    if points==[]:
        ii = 0
        while points==[]:  #  如果返回的坐标为空,继续循环查找
            img = screen.grabWindow(hld).toImage()
            img.save(r'D:\findpic\jietu.bmp')
            time.sleep(2)
            img1 = load_image_file(r'D:\findpic\jietu.bmp')
            img2 = load_image_file(r'D:\findpic\qhzh.bmp')
            process = MatchImg(img1, img2, 0.9)
            points = process.get_img_center()
            ii+=1
            print('重试' + str(ii))
            if ii>100:
                print('没有')
                exit()  # exit()和quit()都是直接退出程序
    print(points, '点击切换账号')  # 找到图的中心点坐标
    points1 = process.get_template_position()
    print(points1)  # 找到图的左上角和右下角的坐标
    left_down(zjb[1], points[0][0], points[0][1]-40)  # 此处我们按下的点是:横坐标为返回中心横坐标+i,纵坐标为返回中心坐标的纵坐标
    time.sleep(0.1)
    left_up(zjb[1], points[0][0], points[0][1]-40)   # 此处我们弹起的点是:横坐标为返回中心横坐标+i,纵坐标为返回中心坐标的纵坐标
    time.sleep(2)
    img = screen.grabWindow(hld).toImage()
    img.save(r'D:\findpic\jietu.bmp')
    time.sleep(3)
    img1 = load_image_file(r'D:\findpic\jietu.bmp')
    img2 = load_image_file(r'D:\findpic\dc.bmp')
    process = MatchImg(img1, img2, 0.9)
    points = process.get_img_center()
    if points==[]:
        ii = 0
        while points==[]:  #  如果返回的坐标为空,继续循环查找
            img = screen.grabWindow(hld).toImage()
            img.save(r'D:\findpic\jietu.bmp')
            time.sleep(2)
            img1 = load_image_file(r'D:\findpic\jietu.bmp')
            img2 = load_image_file(r'D:\findpic\dc.bmp')
            process = MatchImg(img1, img2, 0.9)
            points = process.get_img_center()
            ii+=1
            print('重试' + str(ii))
            if ii>100:
                print('没有')
                exit()  # exit()和quit()都是直接退出程序
    print(points, '点击登出')  # 找到图的中心点坐标
    points1 = process.get_template_position()
    print(points1)  # 找到图的左上角和右下角的坐标
    left_down(zjb[1], points[0][0], points[0][1]-40)  # 此处我们按下的点是:横坐标为返回中心横坐标+i,纵坐标为返回中心坐标的纵坐标
    time.sleep(0.1)
    left_up(zjb[1], points[0][0], points[0][1]-40)   # 此处我们弹起的点是:横坐标为返回中心横坐标+i,纵坐标为返回中心坐标的纵坐标
    time.sleep(10)
    img = screen.grabWindow(hld).toImage()
    img.save(r'D:\findpic\jietu.bmp')
    time.sleep(3)
    img1 = load_image_file(r'D:\findpic\jietu.bmp')
    img2 = load_image_file(r'D:\findpic\cxdl.bmp')
    process = MatchImg(img1, img2, 0.9)
    points = process.get_img_center()
    if points==[]:
        ii = 0
        while points==[]:  #  如果返回的坐标为空,继续循环查找
            img = screen.grabWindow(hld).toImage()
            img.save(r'D:\findpic\jietu.bmp')
            time.sleep(2)
            img1 = load_image_file(r'D:\findpic\jietu.bmp')
            img2 = load_image_file(r'D:\findpic\cxdl.bmp')
            process = MatchImg(img1, img2, 0.9)
            points = process.get_img_center()
            ii+=1
            print('重试' + str(ii))
            if ii>100:
                print('没有')
                exit()  # exit()和quit()都是直接退出程序
    print(points, '点击红色登录')  # 找到图的中心点坐标
    points1 = process.get_template_position()
    print(points1)  # 找到图的左上角和右下角的坐标
    left_down(zjb[1], points[0][0], points[0][1]-40)
    time.sleep(0.1)
    left_up(zjb[1], points[0][0], points[0][1]-40)
    time.sleep(50)
    #---------------------------------------------结束一个账号任务---------------------------------------------------
xhcs+=1
 
 
 