package com.example.jmacro; import cn.hutool.core.img.ImgUtil; import cn.hutool.json.JSONUtil; import org.w3c.dom.css.Rect; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; public class Main { static Robot robot; static { try { robot = new Robot(); } catch (AWTException e) { throw new RuntimeException(e); } } public static void main(String[] args) throws AWTException { int[] aa = findImage(loadScreen(), loadAnchor("野外")); System.out.println(JSONUtil.toJsonStr(aa)); } public static Rect findImage(BufferedImage bigImage, BufferedImage smallImage) { int bigWidth = bigImage.getWidth(); int bigHeight = bigImage.getHeight(); int smallWidth = smallImage.getWidth(); int smallHeight = smallImage.getHeight(); int[][] bigData = getImageRGB(bigImage); int[][] smallData = getImageRGB(smallImage); int[] target = {-1, -1}; int yEnd = bigHeight - smallHeight; int xEnd = bigWidth - smallWidth; for (int y = 0; y < yEnd; y++) { for (int x = 0; x < xEnd; x++) { // 对关键点进行先期匹配,降低运算复杂度。如果关键点本身就不匹配,就没必要再去匹配小图的每一个像素点 if (ColorUtil.isSimilar(bigData[x][y], smallData[0][0]) && // 左上角 ColorUtil.isSimilar(bigData[x + smallWidth - 1][y], smallData[smallWidth - 1][0]) &&// 右上角 ColorUtil.isSimilar(bigData[x][y + smallHeight - 1], smallData[0][smallHeight - 1]) &&// 左下角 ColorUtil.isSimilar(bigData[x + smallWidth - 1][y + smallHeight - 1], smallData[smallWidth - 1][smallHeight - 1]) && // 右下角 ColorUtil.isSimilar(bigData[x + smallWidth / 2][y + smallHeight / 2], smallData[smallWidth / 2][smallHeight / 2]) //中心点 ) { // 进行全像素匹配 boolean isMatched = checkAllMatch(x, y, smallHeight, smallWidth, bigData, smallData); if (isMatched) { System.out.println("像素点X" + x + " : Y" + y + ",对应的值为:" + bigData[x][y]); // 获取小图的中心位置的点 int centerX = x + smallWidth / 2; int centerY = y + smallHeight / 2; target[0] = centerX; target[1] = centerY; return new int[][]{{x,y},}; return new Rect } } } } return target; } public static int[][] getImageRGB(BufferedImage bfImage) { int width = bfImage.getWidth(); int height = bfImage.getHeight(); int[][] result = new int[width][height]; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { // 对某个像素点的RGB编码并存入数据库 result[x][y] = bfImage.getRGB(x, y) & 0xFFFFFF; // 单独获取每一个像素点的Red,Green,和Blue的值。 // int r = (bfImage.getRGB(x, y) & 0xFF0000) >> 16; // int g = (bfImage.getRGB(x, y) & 0xFF00) >> 8; // int b = bfImage.getRGB(x, y) & 0xFF; } } return result; } private static boolean checkAllMatch(int x, int y, int smallHeight, int smallWidth, int[][] bigData, int[][] smallData) { boolean isMatched = true; for (int smallY = 0; smallY < smallHeight; smallY++) { for (int smallX = 0; smallX < smallWidth; smallX++) { // 如果发现有一个像素点,两者的值不一样,则认为不相等,如果不相等,则没必要继续比较其它点. if (!ColorUtil.isSimilar(bigData[x + smallX][y + smallY], smallData[smallX][smallY])) { isMatched = false; return isMatched; } } } return isMatched; } // 获取屏幕截图 static BufferedImage loadScreen() { // 获取缺省工具包 Toolkit tk = Toolkit.getDefaultToolkit(); // 屏幕尺寸规格 Dimension di = tk.getScreenSize(); LogUtil.info("获取屏幕尺寸({},{})", di.width, di.height); Rectangle rec = new Rectangle(0, 0, di.width, di.height); return robot.createScreenCapture(rec); } static BufferedImage loadAnchor(String anchor) { return ImgUtil.read(new File("anchor", anchor + ".png")); } }