實現原理
- 截取當前屏幕
- 讀取需要查找的圖片
- 抽取特征
- 根據特征遍歷屏幕找到符合特征的塊
- 把找到的特征塊和圖片進行精確對比
代碼如下
public interface ImageFinder {/*** 查詢到匹配的圖片* @param image 需要查找的圖片* @return*/List<Coordinate> match(BufferedImage image,
double percent);}
public class Coordinate {
private int x;
private int y;
public Coordinate(
int x,
int y) {
this.x = x;
this.y = y;}
public int getX() {
return x;}
public void setX(
int x) {
this.x = x;}
public int getY() {
return y;}
public void setY(
int y) {
this.y = y;}}
public class ColorBlock {int[][] rgbs;
private int width;
private int height;
private Point leftTop;
private Point rightTop;
private Point leftBottom;
private Point rightBottom;
private Point center;
private int count =
0;
public ColorBlock(BufferedImage image){
this.width = image.getWidth();
this.height = image.getHeight();
this.rgbs =
new int[
this.width][
this.height];
for(
int x=
0;x<
this.width;x++){
for(
int y=
0; y<
this.height;y++){
this.rgbs[x][y] = image.getRGB(x,y);count = count+
1;}}
this.leftTop = Point.ZERO;
this.leftTop.setRgb(rgbs);
this.rightTop =
new Point(
this.width-
1,
0);
this.rightTop.setRgb(rgbs);
this.leftBottom =
new Point(
0,
this.height-
1);
this.leftBottom.setRgb(rgbs);
this.rightBottom =
new Point(
this.width-
1,
this.height-
1);
this.rightBottom.setRgb(rgbs);
this.center =
new Point(
this.width/
2,
this.height/
2);
this.center.setRgb(rgbs);}
public static class Point{public static final Point ZERO =
new Point(
0,
0);
private int x;
private int y;
private int rgb;
public Point(
int x,
int y) {
this.x = x;
this.y = y;}
public Point(
int x,
int y,
int rgb) {
this(x,y);
this.rgb = rgb;}
public int getX() {
return x;}
public void setX(
int x) {
this.x = x;}
public int getY() {
return y;}
public void setY(
int y) {
this.y = y;}
public int getRgb() {
return rgb;}
public void setRgb(
int rgb) {
this.rgb = rgb;}
public void setRgb(
int[][] block){
this.rgb = block[
this.getX()][
this.getY()];}}
public Point
getLeftTop() {
return leftTop;}
public void setLeftTop(Point leftTop) {
this.leftTop = leftTop;}
public Point
getRightTop() {
return rightTop;}
public void setRightTop(Point rightTop) {
this.rightTop = rightTop;}
public Point
getLeftBottom() {
return leftBottom;}
public void setLeftBottom(Point leftBottom) {
this.leftBottom = leftBottom;}
public Point
getRightBottom() {
return rightBottom;}
public void setRightBottom(Point rightBottom) {
this.rightBottom = rightBottom;}
public Point
getCenter() {
return center;}
public void setCenter(Point center) {
this.center = center;}
public boolean isPointMatch(
int leftTop,
int rightTop,
int leftBottom,
int rightBottom,
int center){
return this.leftTop.getRgb()==leftTop&&
this.rightTop.getRgb()==rightTop&&
this.leftBottom.getRgb()==leftBottom&&
this.rightBottom.getRgb()==rightBottom&&
this.center.getRgb()==center;}
public int getWidth() {
return width;}
public void setWidth(
int width) {
this.width = width;}
public int getHeight() {
return height;}
public void setHeight(
int height) {
this.height = height;}
public boolean allMatch(Coordinate coordinate,
int[][] screen,
double percent){
int centerX =
this.getWidth()/
2;
int centerY =
this.getHeight()/
2;
for(
int x=
0;x<
this.getWidth();x++){
if(
this.rgbs[x][centerY]!=screen[x+coordinate.getX()][centerY+coordinate.getY()])
return false;}
for(
int y=
0;y<
this.getHeight();y++){
if(
this.rgbs[centerX][y]!=screen[coordinate.getX()+centerX][y+coordinate.getY()])
return false;}
int temp=
0;
for(
int x =
0;x<
this.getWidth();x++){
for(
int y=
0;y<
this.getHeight();y++){
if(
this.rgbs[x][y]==screen[x+coordinate.getX()][y+coordinate.getY()]) temp++;}}
return ((
double)temp/(
double) count)>percent;}
}
public class ScreenImageFinder implements ImageFinder {protected Robot robot ;
protected BufferedImage screen;
protected Dimension dimension;
public ScreenImageFinder() {
try {dimension = Toolkit.getDefaultToolkit().getScreenSize();robot =
new Robot();screen = robot.createScreenCapture(
new Rectangle(
0,
0,dimension.width,dimension.height));}
catch (AWTException e) {e.printStackTrace();}}
public List<Coordinate>
match( BufferedImage image,
double percent) {
int[][] screenRgbs = getRGB(screen);ColorBlock block =
new ColorBlock(image);List<Coordinate> coordinates =
new ArrayList<>();
for(
int x=
0;x<screen.getWidth()-block.getWidth();x++){
for(
int y=
0;y<screen.getHeight()-block.getHeight();y++){
int topLeft = screenRgbs[x][y];
int topRight= screenRgbs[x+ block.getRightTop().getX()][y+block.getRightTop().getY()];
int bottomLeft= screenRgbs[x+ block.getLeftBottom().getX()][y+block.getLeftBottom().getY()];
int bottomRight= screenRgbs[x+ block.getRightBottom().getX()][y+block.getRightBottom().getY()];
int center= screenRgbs[x+ block.getCenter().getX()][y+block.getCenter().getY()];
if(!block.isPointMatch(topLeft,topRight,bottomLeft,bottomRight,center))
continue;coordinates.add(
new Coordinate(x,y));}}
return coordinates.stream().filter(coordinate -> block.allMatch(coordinate,screenRgbs,percent)).collect(toList());}
private boolean colorCompare(
int source,
int compare){
return source==compare;}
public Robot
getRobot() {
return robot;}
public void setRobot(Robot robot) {
this.robot = robot;}
public BufferedImage
getScreen() {
return screen;}
public void setScreen(BufferedImage screen) {
this.screen = screen;}
public Dimension
getDimension() {
return dimension;}
public void setDimension(Dimension dimension) {
this.dimension = dimension;}}- 測試代碼ImageFinder finder =
new ScreenImageFinder();BufferedImage search = ImageIO.read(Application.class.getClassLoader().getResourceAsStream(
"help.png"));
long start = System.currentTimeMillis();List<Coordinate> coordinateList = finder.match(search,
0.99);System.out.println(
"耗時:"+(System.currentTimeMillis()-start));coordinateList.stream().findAny().ifPresent(coordinate -> System.out.println(String.format(
"find help image x:%d,y:%d",coordinate.getX(),coordinate.getY())));
耗時
:219find help image x:551,
y:24
總結
以上是生活随笔為你收集整理的用java实现屏幕找图的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。