前言
先说一下整体思路,模拟器登录小猿口算后,然后将窗口位置固定,先录制手势脚本,也就是大于号和小于号,然后绑定快捷键触发,然后使用Java的截图方法截取指定位置的图片,然后将图片流传给OCR,识别出数字后然后进行运算,运算完成后触发前面绑定的快捷键即完成一次做题。
1 下载模拟器
此处使用的模拟器是BlueStacks 5,自己去官网下载对应的安装包,此处不再赘述,安装完成后,用里面自带的浏览器去下载小猿口算,此处需要注意,里面内置的是谷歌浏览器,需要将搜索引擎改为百度浏览器,下载完成后打开小猿口算,将其竖置。
1.1 录制脚本
大致流程如此,可能不够详细,剩下自己探索
1.2 调整模拟器手机的分辨率
我的电脑的分辨率是2560*1440,你需要调整至和你电脑分辨率一样的尺寸,此处是为了方便截图定位用的,模拟器右下角有个设置,不再赘述。
1.3 利用截图工具定位
我使用的截图工具是Snipate,截取两个数字的位置,以左面的数字为例,需要知道其左上角那个点的位置坐标和需要截取的宽度和高度。
2.编写代码
2.1 安装OCR
去官网下载ocr的安装教程,此处不再赘述
2.2 导入依赖包
<dependency>
<groupId>net.sourceforge.tess4j</groupId>
<artifactId>tess4j</artifactId>
<version>5.2.0</version>
</dependency>
2.3 编码
需要注意的是,里面的有个进程等待时间,自己去进行测试,找到最合适的时间,既不会绘制的重叠,又不会太慢,然后此处写的是死循环,就是比赛之前打开脚本就行,识别出不是数字会自动返回不进行比较,直到右面一个数字识别到为止,此处的方法可以进行优化,如果时间一直是固定的其实效率低,自己去研究吧!
package com.ruoyi.web.controller.kousuan;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;
import sun.net.www.content.image.png;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.awt.AWTException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
/**
* @author Danyang
* @version 1.0
* @description
* @date 2024/10/11 0:07
*/
public class XiaoYuanKouSuan {
public static void main(String[] args) throws Exception {
Robot robot = new Robot();
Tesseract tesseract = new Tesseract();
tesseract.setDatapath("C:\\Program Files\\Tesseract-OCR\\tessdata");
tesseract.setLanguage("eng");
tesseract.setTessVariable("tessedit_char_whitelist", "0123456789");
Rectangle captureRect1 = new Rectangle(294, 297, 59, 92);
Rectangle captureRect2 = new Rectangle(396, 297, 59, 92);
int i = 0;
while (true) {
//截图
BufferedImage screenCapture1 = robot.createScreenCapture(captureRect1);
BufferedImage screenCapture2 = robot.createScreenCapture(captureRect2);
int num1 = 0;
int num2 = 0;
//识别 第一个数异常直接返回
String num_1 = tesseract.doOCR(screenCapture1);
try {
num1 = Integer.parseInt(num_1.trim());
}catch (NumberFormatException e){
continue;
}
String num_2 = tesseract.doOCR(screenCapture2);
try {
num2 = Integer.parseInt(num_2.trim());
}catch (NumberFormatException e){
continue;
}
if (num1 > num2) {
robot.keyPress(KeyEvent.VK_R);
robot.keyRelease(KeyEvent.VK_R);
Thread.sleep(1000);
System.out.println(num1+">"+num2);
i++;
} else if (num1 < num2) {
robot.keyPress(KeyEvent.VK_L);
robot.keyRelease(KeyEvent.VK_L);
Thread.sleep(1000);
System.out.println(num1+"<"+num2);
i++;
}
}
}
}