请问如何实现全分辨率识图?
@SuperMonster003 和各位代码大佬,有个问题请教一下,从现在的版本看,现在的识图功能函数findImage()是模块匹配,通过截小图,并在全屏截图中识别的方法,这样基本上只可以本手机自身的截图(即分辨率是固定的),如果换了一个不同分辨率的手机,就会找不到图片。 所以请教一下,有什么方法可以实现分辨率识图?以方便我的脚本和截图在其他手机上正常工作。感谢!!
另外,有没有适配autojs6.6的手机截图和编辑工具推荐,以方便截图和简单的编辑?
[images.findImage(img, template[, options])](https://docs.autojs6.com/#/image?id=imagesfindimageimg-template-options)
img {Image} 大图片
template {Image} 小图片(模板)
options {Object} 找图选项
找图. 在大图片img中查找小图片template的位置(模块匹配), 找到时返回位置坐标(Point), 找不到时返回null.
这个问题很简单啊。 在大图里寻找小图,你只要确保大图是全屏截图就行了。 因为全屏截图的图片宽和高尺寸,就等于分辨率。 什么分辨率截的图,图片就是多大。
你在这张图片里面找到的小图坐标,就是对应这个分辨率的。
这个问题很简单啊。 在大图里寻找小图,你只要确保大图是全屏截图就行了。 因为全屏截图的图片宽和高尺寸,就等于分辨率。 什么分辨率截的图,图片就是多大。
你在这张图片里面找到的小图坐标,就是对应这个分辨率的。
感谢解答。但我所表述的不是这个意思,比如,我的手机A的分辨率是896X1848,手机B的分辨率是1344X2772;我用手机A截屏并剪裁一个小图片(比如:完成按钮.jpg)用于以后运行代码时识别某个按钮;之后,我在手机A上运行代码
requestScreenCapture();
var img = captureScreen();
var templ = images.read("/sdcard/完成按钮.jpg");
var p = findImage(img, templ);
if(p){
toast("找到啦:" + p);
}else{
toast("没找到");
}
这时会正常找到截图并返回 找到啦:{516.0, 202.0}
但当我把完成按钮.jpg copy到手机B后,在手机B上运行同样的代码,则会因为找不到图而返回 没找到。
其原因是两台手机的分辨率不同。我的理解,findImage是基于模块找图(即同分辨率)的原理,所以不能找到,那么我就是想一个能让手机B中也可以正常运行代码并能识别图片的方法。
(主要是不想在手机B中重新截一次图,一是不方便,二是B手机是家里另一个人在用,他并不懂这些,一切还得我去折腾,所以不想这么麻烦)
为什么要用A手机的截图,拿去给B手机用呢? 代码在哪个手机上运行,就在哪个手机上截图就好了。 方案一:你的程序本来就要放在他手机上运行,就让程序自己去截图就好了。 开启“投影媒体”权限,就全自动了。
方案二:而且,你既然说有按钮,那就更简单了。 找到该按钮
let button = className("android.widget.Button").text("你的按钮").findOne();
当然你的按钮可能是别的参数,但只要能通过程序找到,那么:
let bounds=button.bounds();
你可以获得它的bounds,这是一个数组,是这个组件的边缘坐标,对应布局分析里你所看到的坐标,它可能长这个样子:[203, 1033, 325, 1088] 然后截图就能使用这个坐标了。
let x=bounds[0];
let y=bounds[1];
let w=bounds[2]-x;
let h=bounds[3]-y;
方案三:可以利用这两个函数(但不保证行得通): setScaleBaseX(1080); setScaleBaseY(2400); 然后x使用cX(),y使用cY()。 setScaleBaseX、setScaleBaseY这两个函数设置你手机的分辨率。 当程序在其它分辨率手机上运行的时候,cX()、cY()设置的坐标会根据前面两个函数设置的分辨率进行自动伸缩。 在大部分的情况下是能伸缩的合适的坐标的。
每次我都是用这个用来初始化坐标,然后用方案二来替补。 如果找到了可以参照的组件,就更新坐标。
说实话,我没搞懂你的需求。 如果你只是为了找到一个按钮,通过findOne();无疑是最简单的方式,根本不需要截图,不需要从大图找小图。
方案四: findImage函数调整相识度。
var p = findImage(pictures2, wx, {
threshold: 0.8 // 相似度0.8
});
我最低的时候,能把相似度调到0.1
我曾经有一段代码是这么写的:
setScaleBaseX(1080);
setScaleBaseY(2400);
// 截全屏
var pictures2 = images.clip(captureScreen(), 0, 0, dwidth, dheight);
images.save(pictures2, "./tmp/pictures2.png", "png", 100);
// 截小图,根据setScaleBaseX、setScaleBaseY设置的分辨率会自动伸缩
var hk_auto = images.clip(pictures2,
cX(165), cY(1276), (cX(349) - cX(165)), (cY(1460) - cX(1276)));
images.save(hk_auto, "./tmp/hk_auto.png", "png", 100);
// 然后就可以开始找图了
var p = findImage(pictures2, hk_auto, {
threshold: 0.8 // 相似度0.8
});
后来我改成了这样,的写法获取坐标:
function getClipParam() {
let x = cX(101);
let y = cY(638);
var param = {
x: x,
y: y,
w: (cX(979) - x),
h: (cY(1622) - y)
};
let ycdj = textStartsWith("请在下图依次点击").findOne(2500);
if (ycdj) {
//找到合适的父组件
while (ycdj.right() < dwidth * 2 / 3) {
ycdj = ycdj.parent();
}
param.x = ycdj.left();
param.y = ycdj.top();
param.w = ycdj.right() - param.x;
}
let tida = className("android.widget.Button")
.text("提交答案").findOne(2500);
if (tida) {
param.h = tida.top() - param.y;
}
return param;
}
先用cX,cY内置一个截图需要的数组,如果找到了参照的组件,再根据组件的边缘坐标,按需来构建更新坐标参数。 拿到这些参数,再截图,肯定能获取到自己需要的截图模样。
也就是说,不论是大图还是小图,都在目标手机里自动截取。 你也不用去传输截图.jpg, 只要对方更新脚本,其它啥也不用管,只管运行就行。 自动适应分辨率,全程全自动。
大图如下:
截取的小图如下:
@wengzhenquan 感谢!你的这个高级,我学习学习!
@wengzhenquan 感谢!你的这个高级,我学习学习!
加油,就是3套方案一起用。 方案一:让大图、小图两张图都在对方手机自动截取,让程序自己动。 方案三:用setScaleBaseX、setScaleBaseY、cX、cY自动伸缩坐标来截小图。这些坐标就设置你自己的手机分辨率的坐标就行。 基本到这里就可以了。 结合方案二,寻找参照组件的边缘坐标,来更新截图大小的参数,能确保万无一失。
如果需要的目标组件难以直接找到。 还可以通过 控件节点 (UiObject)来辅助。 parent 获取父控件。 child(i) 获取子控件。 sibling(i)获取兄弟控件。 等等。
有很多丰富的函数可供你来使用,以助你找到可参照的控件,详情可查看文档。
发现还是要多阅读文档 我发现超时的可以全用 wait自己不需要再写一个啦😂