当前位置:  编程技术>java/j2ee

Java实现图片对比功能

    来源: 互联网  发布时间:2014-11-07

    本文导语:    之前用按键精灵写过一些游戏辅助,里面有个函数叫FindPic,就上在屏幕范围查找给定的一张图片,返回查找到的坐标位置。   现在,Java来实现这个函数类似的功能。   算法描述: 屏幕截图,得到图A,(查找的目标图...

  之前用按键精灵写过一些游戏辅助,里面有个函数叫FindPic,就上在屏幕范围查找给定的一张图片,返回查找到的坐标位置。

  现在,Java来实现这个函数类似的功能。

  算法描述:

屏幕截图,得到图A,(查找的目标图片为图B);
遍历图A的像素点,根据图B的尺寸,得到图B四个角映射到图A上的四个点;
得到的四个点与图B的四个角像素点的值比较。如果四个点一样,执行步骤4;否则,回到步骤2继续;
进一步对比,将映射范围内的全部点与图B全部的点比较。如果全部一样,则说明图片已找到;否则,回到步骤2继续;
  这里,像素之间的比较是通过BufferedImage对象获取每个像素的RGB值来比较的。如下,将BufferedImage转换为int二维数组:

   /**
   * 根据BufferedImage获取图片RGB数组
   * @param bfImage
   * @return
   */
   public static 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;
   }

   比较两个像素点的RGB值是否相同,是通过异或操作比较的(据说比==效率更高),如果异或操作后得到的值为0,说明两个像素点的RGB一样,否则不一样。

  下面附上算法完整java代码:

 package com.jebysun.test.imagefind;
 
 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 java.io.IOException;
 
 import javax.imageio.ImageIO;
 /**
 * 屏幕上查找指定图片
 * @author Jeby Sun
 * @date 2014-09-13
 * @website http://www.jebysun.com
 */
 public class ImageFindDemo {
   
   BufferedImage screenShotImage;  //屏幕截图
   BufferedImage keyImage;      //查找目标图片
   
   int scrShotImgWidth;       //屏幕截图宽度
   int scrShotImgHeight;       //屏幕截图高度
   
   int keyImgWidth;         //查找目标图片宽度
   int keyImgHeight;         //查找目标图片高度
   
   int[][] screenShotImageRGBData;  //屏幕截图RGB数据
   int[][] keyImageRGBData;     //查找目标图片RGB数据
   
   int[][][] findImgData;      //查找结果,目标图标位于屏幕截图上的坐标数据 
   
   
   public ImageFindDemo(String keyImagePath) {
     screenShotImage = this.getFullScreenShot();
     keyImage = this.getBfImageFromPath(keyImagePath);
     screenShotImageRGBData = this.getImageGRB(screenShotImage);
     keyImageRGBData = this.getImageGRB(keyImage);
     scrShotImgWidth = screenShotImage.getWidth();
     scrShotImgHeight = screenShotImage.getHeight();
     keyImgWidth = keyImage.getWidth();
     keyImgHeight = keyImage.getHeight();
     
     //开始查找
     this.findImage();
     
   }
   
   /**
   * 全屏截图
   * @return 返回BufferedImage
   */
   public BufferedImage getFullScreenShot() {
     BufferedImage bfImage = null;
     int width = (int) Toolkit.getDefaultToolkit().getScreenSize().getWidth();
     int height = (int) Toolkit.getDefaultToolkit().getScreenSize().getHeight();
     try {
       Robot robot = new Robot();
       bfImage = robot.createScreenCapture(new Rectangle(0, 0, width, height));
     } catch (AWTException e) {
       e.printStackTrace();
     }
     return bfImage;
   }
   
   /**
   * 从本地文件读取目标图片
   * @param keyImagePath - 图片绝对路径
   * @return 本地图片的BufferedImage对象
   */
   public BufferedImage getBfImageFromPath(String keyImagePath) {
     BufferedImage bfImage = null;
     try {
       bfImage = ImageIO.read(new File(keyImagePath));
     } catch (IOException e) {
       e.printStackTrace();
     }
     return bfImage;
   }
   
   /**
   * 根据BufferedImage获取图片RGB数组
   * @param bfImage
   * @return
   */
   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;
   }
   
   
   /**
   * 查找图片
   */
   public void findImage() {
     findImgData = new int[keyImgHeight][keyImgWidth][2];
     //遍历屏幕截图像素点数据
     for(int y=0; y

    
 
 

您可能感兴趣的文章:

  • 使用java jdk中的LinkedHashMap实现简单的LRU算法
  • java.util.Date 和 java.slq.Date 如何最简单实现互换?
  • java tomcat实现Session对象的持久化原理及配置方法介绍
  • 不太明白,利用RMI实现JAVA分布式应用 和 EJB实现JAVA分布式应用有什么区别。
  • java实现判断字符串是否全是数字的四种方法代码举例
  • java的API中有没有既实现了Map接口又实现了List接口的类?
  • java序列化实现Serializable接口
  • 我是java新手,请问java中与平台相关的操作是怎样实现的
  • java中Spring框架介绍及如何实现对Bean的管理
  • java文件复制代码片断(java实现文件拷贝)
  • java Servlet实现Session创建存取以及url重写代码示例
  • 要做一个在applet,实现可以托拽的图形(比如长方形和线段等)?那位高手有资料?或者有没有java的第三方类库实现此功能?
  • java 与 C++ 实现后绑定的方法
  • XUL的Java实现 javaXUL
  • 用JAVA实现与QQ相同的功能!
  • 请问《软件工程java语言实现》一书在那里能下载
  • 如何实现Java下的回调函数!
  • Java实现的XForms Chiba
  • Java的SAMBA客户端实现 jCIFS
  • Lua 实现的 Java 虚拟机 luje
  • yaml 的 java 实现 JYaml
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 在下想学习Java,请教各位大侠,Java 有哪功能
  • java中如何实现拖拉的功能?
  • VBScript中FormatNumber(expression ,0,-1)是什么功能?用java怎么替换?
  • 请问既会JAVA又会VC的大侠:JAVA调试时是否有类似于VC中的TRACE功能
  • java编程可实现一些什么样的功能?
  • java功能调查
  • 不知到在JAVA中能否实现下列功能:
  • java中有没有和javascript中escape()功能一样的方法?
  • 请教java中如何实现vb中chr() ,asc() 类似的功能?
  • Java Doc 没有搜索功能,如果像msdn就好了,谁有好的方法???
  • 如何在JAVA中实现类似VC中sprintf的功能
  • 想用java实现这样的功能,不知行不行??
  • java中如何实现类似vb中的chr()函数的功能?
  • java 实现 vb中timer控件的功能?
  • java的网络功能类socket是作用于哪一层的,偶要写一个更底层的网络通讯程序,用到了APDU协议,用java能实现吗?偶其他的语言不熟!!!!
  • 如何用vim的map功能快速编译运行java文件?
  • 有没有类似于字典一样的,介绍JAVA 各种包的功能的书?
  • 寻找一种较为方便的java代码文本编辑器(比如带有语法及关键字变色功能)?
  • java中如何实现拷屏粘贴功能!高分!!
  • java中没有枚举变量,类似的功能如何简单实现?
  • java命名空间java.sql类types的类成员方法: java_object定义及介绍
  • 我想学JAVA ,是买THINK IN JAVA 还是JAVA2核心技术:卷1 好???
  • java命名空间java.awt.datatransfer类dataflavor的类成员方法: imageflavor定义及介绍
  • 请问Java高手,Java的优势在那里??,Java主要适合于开发哪类应用程序
  • java命名空间java.lang.management类managementfactory的类成员方法: getcompilationmxbean定义及介绍
  • 如何将java.util.Date转化为java.sql.Date?数据库中Date类型对应于java的哪个Date呢
  • java命名空间java.lang.management接口runtimemxbean的类成员方法: getlibrarypath定义及介绍
  • 谁有电子版的《Java编程思想第二版(Thinking in java second)》和《Java2编程详解(special edition java2)》?得到给分
  • java命名空间java.lang.management接口runtimemxbean的类成员方法: getstarttime定义及介绍
  • 本人想学java,请问java程序员的待遇如何,和java主要有几个比较强的方向
  • java命名空间java.awt.datatransfer类dataflavor的类成员方法: stringflavor定义及介绍




  • 特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3