需求:根据图片定位在windows的位置并把鼠标移动过去
思路:
- 获取桌面图片,加载为RGB
- 获取需求图片,加载为RGB
- 遍历桌面RGB,找到和图片RGB吻合的位置
- 定位,移动鼠标
上代码
package com.example.robot;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
/**
* 根据图片定位
* @author liutong
* @date 2022/4/23 15:15
*/
public class FindPso {
/**
* 目标图片
*/
BufferedImage keyImage;
/**
* 当前屏幕宽度
*/
int scrShotImgWidth;
/**
* 当前屏幕高度
*/
int scrShotImgHeight;
/**
* 目标图片宽度
*/
int keyImgWidth;
/**
* 目标图片高度
*/
int keyImgHeight;
/**
* 当前屏幕RGB数据
*/
int[][] screenShotImageRGBData;
/**
* 目标图片RGB数据
*/
int[][] keyImageRGBData;
/**
* 结果X
*/
int findX;
/**
* 结果Y
*/
int findY;
private static Robot robot = null;
/**
* 当前屏幕截屏
*/
private static BufferedImage screenShotImage = null;
// private static Map map = new LinkedHashMap<>();
static {
try {
robot = new Robot();
} catch (AWTException e) {
e.printStackTrace();
}
int width = (int) Toolkit.getDefaultToolkit().getScreenSize().getWidth();
int height = (int) Toolkit.getDefaultToolkit().getScreenSize().getHeight();
try {
screenShotImage = robot.createScreenCapture(new Rectangle(0, 0, width, height));
} catch (Exception e) {
e.printStackTrace();
}
}
public FindPso(){
}
public FindPso(String keyImagePath, String screenshot) {
//读取目标图片
keyImage = this.getBfImageFromPath(keyImagePath);
//获取截屏RGB
screenShotImageRGBData = this.getImageGRB(screenShotImage);
//获取图片RGB
keyImageRGBData = this.getImageGRB(keyImage);
//获取截屏长宽
scrShotImgWidth = screenShotImage.getWidth();
scrShotImgHeight = screenShotImage.getHeight();
//获取图片长宽
keyImgWidth = keyImage.getWidth();
keyImgHeight = keyImage.getHeight();
//开始查找
this.findImageXY();
}
/**
* 根据像素点定位
* @author liutong
* @date 2022/4/23 15:12
* @return null
*/
public void findImageXY() {
//遍历屏幕截图像素点数据
for (int y = 0; y < scrShotImgHeight - keyImgHeight; y++) {
for (int x = 0; x < scrShotImgWidth - keyImgWidth; x++) {
if ((keyImageRGBData[0][0] ^ screenShotImageRGBData[y][x]) == 0
&& (keyImageRGBData[0][keyImgWidth - 1] ^ screenShotImageRGBData[y][x + keyImgWidth - 1]) == 0
&& (keyImageRGBData[keyImgHeight - 1][keyImgWidth - 1] ^ screenShotImageRGBData[y + keyImgHeight - 1][x + keyImgWidth - 1]) == 0
&& (keyImageRGBData[keyImgHeight - 1][0] ^ screenShotImageRGBData[y + keyImgHeight - 1][x]) == 0) {
boolean isFinded = isMatchAll(y, x);
//如果比较结果完全相同,则说明图片找到,填充查找到的位置坐标数据到查找结果数组。
if (isFinded) {
//0
int minY = y;
int maxY = y + keyImgHeight;
findY = ((minY + maxY) / 2);
//1
int minX = x;
int maxX = x + keyImgWidth;
findX = ((minX + maxX) / 2);
}
}
}
}
}
/**
* 根据图片获取IO
* @author liutong
* @date 2022/4/23 15:25
* @param keyImagePath 路径
* @return java.awt.image.BufferedImage
*/
public BufferedImage getBfImageFromPath(String keyImagePath) {
BufferedImage bfImage = null;
try {
bfImage = ImageIO.read(new File(keyImagePath));
} catch (IOException e) {
e.printStackTrace();
}
return bfImage;
}
/**
* 根据图片IO获取RGB
* @author liutong
* @date 2022/4/23 15:27
* @param bfImage 图片IO
* @return int[][]
*/
public int[][] getImageGRB(BufferedImage bfImage) {
int width = bfImage.getWidth();
int height = bfImage.getHeight();
int[][] result = new int[height][width];
for (int h = 0; h < height; h++) {
for (int w = 0; w < width; w++) {
//使用getRGB(w, h)获取该点的颜色值是ARGB,而在实际应用中使用的是RGB,所以需要将ARGB转化成RGB,即bufImg.getRGB(w, h) & 0xFFFFFF。
result[h][w] = bfImage.getRGB(w, h) & 0xFFFFFF;
}
}
return result;
}
/**
* 是否全部匹配
* @author liutong
* @date 2022/4/23 15:27
* @param y
* @param x
* @return boolean
*/
public boolean isMatchAll(int y, int x) {
int biggerY = 0;
int biggerX = 0;
int xor = 0;
for (int smallerY = 0; smallerY < keyImgHeight; smallerY++) {
biggerY = y + smallerY;
for (int smallerX = 0; smallerX < keyImgWidth; smallerX++) {
biggerX = x + smallerX;
if (biggerY >= scrShotImgHeight || biggerX >= scrShotImgWidth) {
return false;
}
xor = keyImageRGBData[smallerY][smallerX] ^ screenShotImageRGBData[biggerY][biggerX];
if (xor != 0) {
return false;
}
}
}
return true;
}
public static boolean touchPic(String path) {
//移动到定位
boolean res = findPoint(path);
System.out.println("移动到定位:"+res);
if(!res){
return false;
}
return true;
}
/**
* 找到定位并移动到定位点
* @param path
* @return
*/
public static boolean findPoint(String path){
return findPoint(path,true);
}
public static boolean findPoint(String path,boolean move){
FindPso demo = new FindPso(path,"");
System.out.println("找到:"+demo.findX+","+demo.findY);
if(move){
// 移动五次以上才会比较精确
for (int i = 0; i < 10; i++) {
robot.mouseMove(demo.findX, demo.findY);
}
}
return true;
}
public static void main(String[] args) {
touchPic("C:\\Users\\Administrator\\Pictures\\Saved Pictures\\a.png");
}
}
版权声明:本文为wai_58934原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。