桌面应用程序的UI自动化,除了解析应用层级控件外,还可以通过图片定位获取目标元素位置,对其进行点击、双击、滚动等操作。
python可用opencv库操作图片。
opencv安装
- sudo apt install python-opencv
图片比对
import cv2
import pyautoguidef match_img(small_image, big_image=None, confidence_value=0.9):"""small_image: 目标图片的路径big_image: 需要匹配的图片,在大图中去匹配目标图片confidence_value: 匹配度,0-1"""# 屏幕截图screen = pyautogui.screenshot()screen.save('/tmp/screen.png')# 获取屏幕截图数组信息screen_array = cv2.imread('/tmp/screen.png')if big_image:# 获取大图的数组信息big_img_array = cv2.imread('/tmp/screen.png')# 先获取大图在屏幕中的位置res = cv2.matchTemplate(screen_array, big_img_array, cv2.TM_CCOEFF_NORMED)# 从一个矩阵中找出全局的最大值和最小值minmax = cv2.minMaxLoc(res)# 取匹配度最大的坐标,这个也代表了大图的顶点坐标pos_start_big = minmax[3]else:# 如果没有传入大图,则用屏幕截图当做大图big_img_array = screen_arraypos_start_big = [0, 0]# 获取目标图片的数组信息small_img_array = cv2.imread(small_image)# 调用matchTemplate方法进行匹配,cv.TM_CCOEFF_NORMED是匹配的方法:该方法使用归一化的平方差进行匹配,最佳匹配在结果为0处res = cv2.matchTemplate(big_img_array, small_img_array, cv2.TM_CCOEFF_NORMED)# 从一个矩阵中找出全局的最大值和最小值minmax = cv2.minMaxLoc(res)# 取匹配度最大的坐标,注意这是相对大图的顶点坐标pos_start = minmax[3]# 匹配对象的中心坐标x y,这里获取的是绝对坐标x = int(pos_start_big[0] + pos_start[0]) + int(small_img_array.shape[1] / 2)y = int(pos_start_big[1] + pos_start[1]) + int(small_img_array.shape[0] / 2)# 取最大的匹配度值similarity = minmax[1]# 如果匹配度不满足条件,直接返回空if similarity < confidence_value:return None# 否则返回目标图片的中心位置return x, y# 调用方法
res = match_img('./img.png', './img_1.png', confidence_value=0.9)
# 通过鼠标移动验证获取的图片位置正确
pyautogui.moveTo(res[0], res[1])
以上代码实现了一个图片匹配方法,返回匹配到的图片坐标。有2种使用方式:
- 直接传入目标图片,这样会在整个屏幕截图中查找目标图片;
- 在一张大图中匹配目标图片,返回的也是目标图片的绝对坐标位置;