【autojs】图色识别状态条
autojs是常用脚本语言,工业上用autojs安卓测试小程序。有些测试逻辑可以用ocr实现,比如说校验页面上有没有特定文本(用ocr),而有些逻辑不涉及文本的差异,比如下面这张风量图,几级分没有文本标签,只有颜色的分别。
怎样识别现在的风量等级呢?先想到图像匹配,用images.clip()方法切下长条状态栏,灰色一组,绿色一组,每组7个,再用images.TemplateMatch方法匹配图像。怎么说呢,一听就很麻烦。
又想到图色,识别指定坐标(x,y)处像素点颜色。想法很美好,在7个状态栏上各取1个点,判断颜色,就可以得到等级。但这个坐标很可能不是万年不变的,小程序更新可能会微调,换一个不同分辨率不同牌子的手机可能又有位移,怎么“一劳永逸”地识别风量等级?想啊想,想到了,就是我们的爬格子法。大致思路是:
- 框定状态栏的大致范围,再从上到下,或者从左到右,或者围绕圆点顺/逆时针旋转,或者沿着其他可能的顺=路径,以固定步长遍历整个范围,每一步i进行图色比对,判断该步取色是为图色i。
- 若本次读到的图色i与图色i-1一致,不作处理。
- 若图色i与图色i-1不一致,给更新图色i的计数,或者直接返回计数结果
上代码
function findColor(img,x,y){x = x/720*device.widthy = y/1612*device.heightvar dot = img.pixel(x,y);//log(dot)// 将点的颜色值转换为字符串形式var color = colors.toString(dot);//log("找到颜色",color,"x=",x,",y=",y)return color}
function compareColor(img,x,y,c0){ let c1 = findColor(img,x,y)let r = colors.isSimilar(c1,c0,6)//log("颜色对比","目标色",c0,"取到的颜色",c1,r)return r
}
function getWindLevel(img){let cGray = "#ffafb4b7"let cGreen = "#ff00ff57"let cBlue = "#ff1f4f8d"let x = 180let startY = 326let y = startYlet d = 5let cnt = 0let last = "blue"while(y<device.height/2){let isGray = compareColor(img,x,y,cGray)let isGreen = compareColor(img,x,y,cGreen)let isBlue = compareColor(img,x,y,cBlue)if(isGray&&last!="g"){last = "g"cnt++}else if(isGreen){return 7-cnt}else if(isBlue){last = "b"}y += d} return 0
}
requestScreenCapture()
sleep(500)
img= automator.takeScreenshot()
// let img = images.read(files.getSdcardPath()+"/log/test4.jpg")
let c = getWindLevel(img)
log(c)
img.recycle()
代码解析
1. findColor(img,x,y)方法,识别图片xy坐标的像素点颜色,返回值格式"#RRGGBB"
2. compareColor(img,x,y,c0)方法,判断图片xy坐标的像素点颜色是否与c0相似,相似等级为6(可自行修改)
3. getWindLevel方法,cGrey\cBlue\cBlue的值可以通过findColor方法获得。建议操作步骤:
(1)截图保存图片,
(2)打开Windows电脑自带的画图软件,粘贴图片
(3)用鼠标找到颜色点的坐标x0y0(显示在画图软件程序框的左下角状态栏)
(4)调用findColor方法,log输出颜色