话不多说,直接进入正题;
上回简单分析了一下SuperPatrick官网的一个桌面自动化的例子,这次准备简单分析一下关于这个工具桌面图像识别的部分;关于官网给出的讲解也挺详细,里面也有相关代码,本文中的代码也都是来自该文章,地址如下:
http://www.autotestops.com/index/xq/cid/28/id/41.html
首先,图像识别方面我感觉不出意外基本上用的是OpenCv的图像技术,但是这个工具下载下来的dll库中没有Opencv的dll,仔细一想这个工具开发者应该是直接将opencv的dll编译到自己的工具dll中了;上次已经说过关于图像识别的方法,SuperPatrick中目前提供了3个相关方法,如下:
1.全屏图像识别,默认点击一次(左键)
bool findImage(char *strPartImage)
2.相对坐标图像识别,默认点击一次(左键)
bool findStaticImage(char *strPartImage, int left, int top, int right, int bottom)
3.基于窗口句柄的图像识别点击,默认点击一次(左键)
bool findImageByHwnd(char *strClass, char *strTitle, char *strPartImage)
其中findIImage以及findImageByHwnd这两个方法的连续两次点击中间存在延时,而findStaticImage方法中没有延迟,可以实现双击。PS:总感觉是漏掉了加延时;
这里我粗略的分析了一下这几个方法的使用以及运行逻辑,至于如何实现的,可能只能咨询一下开发者了;
方法一:findImage
全屏图像识别点击,顾名思义,这个相对比较好理解,在全屏范围内,截取想要自动化点击的位置的图片,保存到某路径中,然后再代码中调用即可;
代码例:
superpatrick.findImage("D://1//任务栏-电脑管家.png");
这时疑问出现了,这里只是使用截取的小图(想要点击的位置),并没有截取全屏,所以运行的流程应该是每次调用时程序都会自动截取当前的屏幕,然后再使用事先截取好的小图去进行查找对比,找到当前图片的坐标,进而计算出点击的坐标,随后进行点击操作,很可惜截至目前我也没找到全屏截图保存在哪里,应该是缓存一下然后就删掉了;
方法二:findStaticImage
相对坐标图像识别点击,这个我思考了一会儿,试用了一下SuperPatrick定位器提供的截图工具,发现截取图片后,然后复制代码段(复制代码段相关操作官网文章中写的还是很清楚的),发现这里的Static在这里应该翻译成静止的,因为这个方法的后面四个参数分别就是这个图片的左上角坐标以及右下角坐标;
代码例:
superpatrick.findStaticImage("D://1//btn_全面体检.png", 1229, 373, 1408, 422);
就是说在调用这个方法时,想要点击的这个图片位置相对于屏幕来说需要非常的固定,每次自动化的时候都不能变,举个例子类似于电脑桌面的左下角的开始按钮,位置一直不变的这种比较适用,基本的逻辑就是截取桌面一个图片,然后运行代码时针对该四个参数所在的位置进行图片识别,如果没有这个图则返回false不点击,否则为true则会点击一次,相比于findImage这个方法速度要快一点,但是局限性比较大,不能像使用findImage时图片位置可以不固定;
方法三:findImageByHwnd
基于窗口句柄的图像识别点击,说实话对C++了解相对较少,也就大一的时候学习过一段,关于Hwnd这个名词,我还是上网查询了一番才理解这个方法的实际运行逻辑;
Hwnd这里引用一下百度词条里的说法如下:
这里的说法是,每一个打开的窗口,类似于QQ、微信的联系人、聊天页面、浏览器等等窗口Window,都有一个类似于人的身份证信息;
将该说明应用到findImageByHwnd中就是在指定的窗口中搜索想要点击的图片,并进行点击操作;运行逻辑的话,看了一下参数以及官网的说明文章,需要该图片所在父窗口的class,title这两个参数,这个是针对想要点击的图片所在的父窗口的class以及title属性,用这两个属性来指定窗口进行截图(具体怎么定位查看父窗口的这两个属性,网站上的教程有),然后再根据小图的图片路径进行查询,最后返回true则点击一次;
代码例:
superpatrick.findImageByHwnd("NeteaseYoudaoYNoteMainWnd", "有道云笔记", "D://1//有道-我的文件夹.png");
说完有关图像识别的方法过后,当然上一篇文章已经说了,findStaticImage以及findImageByHwnd目前一直都返回true,存在这个问题,在这里再提一下,最后上一波代码分析,这里我把网站里的代码直接贴过来;
import com.sun.jna.Library;
import com.sun.jna.Native;
public class dome {
static boolean isok;
public interface SuperPatrickLibrary extends Library {
void findElement(String pStrId, String pStrName, String pStrClassName, String controlType);
void sendKeys(String pKeysString);
void sendShortCutKeys(String pKeysString);
boolean findImage(String strPartImage);
boolean findStaticImage(String strPartImage, int a, int b, int c, int d);
boolean findImageByHwnd(String strClass, String strTitle, String strPartImage);
}
public static void main(String[] args) throws InterruptedException {
System.setProperty("jna.encoding", "GBK");
String dllPath = "SuperPatrickLibrary.dll所在你本地的绝对路径";
SuperPatrickLibrary superpatrick = (SuperPatrickLibrary) Native.loadLibrary(dllPath, SuperPatrickLibrary.class);
superpatrick.findElement("307", "显示桌面", "", "Button");
isok = superpatrick.findImage("D://1//任务栏-电脑管家.png");
isok = superpatrick.findStaticImage("D://1//btn_全面体检.png", 1229, 373, 1408, 422);
//由于执行较快,看不清效果,添加1s延时
Thread.sleep(1000);
isok = superpatrick.findStaticImage("D://1//任务栏-有道云笔记.png", 635, 1038, 696, 1079);
//由于执行较快,看不清效果,添加0.1s延时
Thread.sleep(100);
isok = superpatrick.findImageByHwnd("NeteaseYoudaoYNoteMainWnd", "有道云笔记", "D://1//有道-我的文件夹.png");
}
}
1:由于调用的dll,所以定义接口加载本地dll映射库方法当然就不用多说了;
2:点击右下角“显示桌面”按钮;
superpatrick.findElement("307", "显示桌面", "", "Button");
isok = superpatrick.findImage("D://1//任务栏-电脑管家.png");
isok = superpatrick.findStaticImage("D://1//btn_全面体检.png", 1229, 373, 1408, 422);
isok = superpatrick.findStaticImage("D://1//任务栏-有道云笔记.png", 635, 1038, 696, 1079);
isok = superpatrick.findImageByHwnd("NeteaseYoudaoYNoteMainWnd", "有道云笔记", "D://1//有道-我的文件夹.png");
OK,截至目前SuperPatrick中的六个方法都简单的了解分析了一下,后续如果研究出好玩儿的工具使用方法,会再讲一讲;