下载adb工具
链接:https://pan.baidu.com/s/1fuobUremdbrs2uQ2Yvo5NQ
提取码:or7m
查看设备
adb devices
测试截图
将截屏文件保存到电脑上
import subprocess
class Screenshot(): # 截取手机屏幕并保存到电脑
def __init__(self):
# 查看连接的手机
connect = subprocess.Popen("adb devices", stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
stdout, stderr = connect.communicate() # 获取返回命令
# 输出执行命令结果结果
stdout = stdout.decode("utf-8")
stderr = stderr.decode("utf-8")
print(stdout)
print(stderr)
def screen(self, cmd): # 在手机上截图
screenExecute = subprocess.Popen(str(cmd), stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
stdout, stderr = screenExecute.communicate()
# 输出执行命令结果结果
stdout = stdout.decode("utf-8")
stderr = stderr.decode("utf-8")
print(stdout)
print(stderr)
def saveComputer(self, cmd): # 将截图保存到电脑
screenExecute = subprocess.Popen(str(cmd), stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
stdout, stderr = screenExecute.communicate()
# 输出调试信息
print(stdout, stderr)
# 先截图保存到手机中保存
cmd1 = r"adb shell /system/bin/screencap -p /sdcard/tmp.png"
# 然后将手机中的图片保存到电脑上
cmd2 = r"adb pull /sdcard/tmp.png tmp.png"
screen = Screenshot()
screen.screen(cmd1)
screen.saveComputer(cmd2)
简化
import subprocess
def get_screen():
# 先截图保存到手机中保存
cmd_screen_cap = "adb shell /system/bin/screencap -p /sdcard/tmp.png"
# 然后将手机中的图片保存到电脑上
cmd_save_computer = "adb pull /sdcard/tmp.png tmp.png"
subprocess.Popen(
cmd_screen_cap,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
shell=True
).communicate()
subprocess.Popen(
cmd_save_computer,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
shell=True
).communicate()
get_screen()
opencv的模板匹配
import cv2
img = cv2.imread('img.png')
part = cv2.imread('close.png')
cv2.imshow('img', img)
cv2.imshow('close', part)
methods = [cv2.TM_SQDIFF_NORMED, cv2.TM_CCORR_NORMED, cv2.TM_CCOEFF_NORMED]
part_height, part_weight = part.shape[:2]
print(part_height, part_weight)
for method in methods:
# print(method)
result = cv2.matchTemplate(img, part, method)
# print(result)
# 根据不同的公式计算不同的值
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
print(min_val, max_val, min_loc, max_loc)
# 根据不同的算法,选择匹配程度最大的区域
if method == cv2.TM_SQDIFF_NORMED:
# 该算法值越小,匹配程度越高
img_loc = min_loc
else:
img_loc = max_loc
br = (img_loc[0] + part_weight, img_loc[1] + part_height)
cv2.rectangle(img, img_loc, br, (0, 0, 255), 2)
cv2.circle(img, (img_loc[0] + part_weight // 2, img_loc[1] + part_height//2), 2, (255, 0, 0))
cv2.imshow("match" + str(method), img)
cv2.imshow("res" + str(method), result)
cv2.waitKey(1000)
cv2.waitKey(0)
可以看到已经能够找到关闭的中心坐标
配合到一起
使用第一种匹配方法,值越小匹配程度越高,在实际测试中发现,第二和第三种方法,会对一些符号误判,对展开列表的箭头和类似形状的文字无法分别
import subprocess
import cv2 as cv
import time
import numpy as np
def get_screen():
# 先截图保存到手机中保存
cmd_screen_cap = "adb shell /system/bin/screencap -p /sdcard/tmp.png"
# 然后将手机中的图片保存到电脑上
cmd_save_computer = "adb pull /sdcard/tmp.png tmp.png"
subprocess.Popen(
cmd_screen_cap,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
shell=True
).communicate()
subprocess.Popen(
cmd_save_computer,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
shell=True
).communicate()
return cv.imread('tmp.png')
# 返回最优匹配图的中心点
def get_center(img, part):
part_height, part_weight = part.shape[:2]
methods = [cv.TM_SQDIFF_NORMED, cv.TM_CCORR_NORMED, cv.TM_CCOEFF_NORMED]
method = methods[0]
result = cv.matchTemplate(img, part, method)
# 根据不同的公式计算不同的值
min_val, max_val, min_loc, max_loc = cv.minMaxLoc(result)
# 根据不同的算法,选择匹配程度最大的区域
if method == cv.TM_SQDIFF_NORMED:
# 该算法值越小,匹配程度越高
img_loc = min_loc
else:
img_loc = max_loc
point = (img_loc[0] + part_weight // 2, img_loc[1] + part_height // 2)
print(np.min(result))
return point if np.min(result) <= .0006 else None
# 点击一个位置
def touch(point):
cmd = f"adb shell input tap {point[0]} {point[1]}"
subprocess.Popen(
cmd,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
shell=True
).communicate()
# 关闭按钮
close = cv.imread('close.png')
# 自动关闭对话框
def auto_close():
img = get_screen()
# 关闭按钮所在中心
point = get_center(img, close)
print(point)
if point:
touch(point)
# 每隔五秒点击一次
duration = 5
while True:
auto_close()
time.sleep(duration)
在实际中通过设置一个很小的阈值来避免出现误判,可以看到大多时候都是没有返回值的,只有出现选项时,才会返回关闭按钮所在的位置坐标,然后自动关闭~