package com.woniu.test; 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; //java圖像模版匹配 //核心思路:用一張小圖片,在一張大圖片裏去尋找,並返回該小圖片所在的座標位置,而後將鼠標移向該處,並實施相應操做。並更據頁面的反饋,進行相應的判斷(斷言) //1.對須要操做的對象進行截圖,獲得一張小圖片,並保存。 //2.對當前屏幕進行截圖,得到一張大圖片,保存或放在內存中 //3.利用模版匹配,在大圖片中,按像素對小圖片進行滑動,找到小圖片所在的位置。 //4.對該座標位置(X,Y),加上小圖片高度的一半(H),寬度的通常(W),獲得該小圖片的中心位置,便是咱們要操做的座標(X+W,Y+H) //5。將鼠標移向該座標(X,Y),並進行相應操做(輸入,單機,雙擊,右鍵等). //6.繼續第二輪操做,第三輪操做。直到第N輪。最後進行模版匹配,來確認是否存在和預期結果一致的小圖片,進而實現斷言。 //因爲是基於的像素匹配,因此,若是界面風格發生變化,可能出現識別不到的狀況。 public class ImageMatch { public static void main(String[] args) throws Exception { ImageMatch im = new ImageMatch(); // BufferedImage bi = im.getScreenShot(); // int[][] result = im.getImageRGB(bi); // for (int y = 0; y < result.length; y++) { // for (int x = 0; x < result[y].length; x++) { // System.out.println(result[y][x]); // } // } Runtime.getRuntime().exec("C:/Windows/system32/calc.exe"); Thread.sleep(3000); String imageDir = System.getProperty("user.dir") + "/wincalc/"; int[] target = im.findImage(imageDir + "3.png"); System.out.println("找到一個點:" + target[0] + " : " + target[1]); } // 截圖 public BufferedImage getScreenShot() { BufferedImage bfImage = null; int captureWidth = (int)Toolkit.getDefaultToolkit().getScreenSize().getWidth(); int captureHeight = (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight(); try { Robot robot = new Robot(); Rectangle screenRect = new Rectangle(0,0,captureWidth,captureHeight); bfImage = robot.createScreenCapture(screenRect); } catch (AWTException e) { e.printStackTrace(); } return bfImage; } // 獲取像素點值 public 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; } // 進行模板匹配 public int[] findImage(String imagePath) { BufferedImage bigImage = this.getScreenShot(); // 當前屏幕截圖 BufferedImage smallImage = null; // 打開預選保存的小圖片 try { smallImage = ImageIO.read(new File(imagePath)); } catch (Exception e) { e.printStackTrace(); } int bigWidth = bigImage.getWidth(); int bigHeight = bigImage.getHeight(); int smallWidth = smallImage.getWidth(); int smallHeight = smallImage.getHeight(); int[][] bigData = this.getImageRGB(bigImage); int[][] smallData = this.getImageRGB(smallImage); int[] target = {-1, -1}; for (int y=0; y<bigHeight-smallHeight; y++) { for (int x=0; x<bigWidth-smallWidth; x++) { // 對關鍵點進行先期匹配,下降運算複雜度。若是關鍵點自己就不匹配,就不必再去匹配小圖的每個像素點。 if (bigData[x][y] == smallData[0][0] && // 左上角 bigData[x+smallWidth-1][y] == smallData[smallWidth-1][0] && // 右上角 bigData[x][y+smallHeight-1] == smallData[0][smallHeight-1] && // 左下角 bigData[x+smallWidth-1][y+smallHeight-1] == smallData[smallWidth-1][smallHeight-1] && // 右下角 bigData[x+smallWidth/2][y+smallHeight/2] == smallData[smallWidth/2][smallHeight/2] ) { // 進行全像素匹配 boolean isMatched = this.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 target; } } } } return target; } // 全像素匹配 public 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 (bigData[x+smallX][y+smallY] != smallData[smallX][smallY]) { isMatched = false; return isMatched; } } } return isMatched; } }
package com.woniu.test; public class CalcTestDemo { static AutoTestRobot robot = new AutoTestRobot(); public static void main(String[] args) throws Exception { Runtime.getRuntime().exec("java -jar D:/Other/JavaSwingCalc.jar"); Thread.sleep(3000); String imageDir = System.getProperty("user.dir") + "/javacalc/"; robot.moveAndInput(imageDir + "numberx.png", "300"); robot.moveAndInput(imageDir + "numbery.png", "200"); robot.moveAndSelect(imageDir + "calctype.png", 1); robot.moveAndClick(imageDir + "docalc.png"); if (robot.isExists(imageDir + "result.png")) { System.out.println("測試成功."); } else { System.out.println("測試失敗."); } } }