前面想做一个JAVA图像识别的小程序,写完代码之后运行发现一直出不了结果,刚开始还以为是代码错了,检查了许久也不知道哪里错了。后来在检测循环的时候就发现,找图运行的相当缓慢,最后发现是 robot.getPixelColor这个方法相当的耗费时间。
写了一段代码进行测试
public static void main(String[] args)
{
try {
Robot robot=new Robot();
long nowTime=System.currentTimeMillis();
BufferedImage bufferedImage=robot.createScreenCapture(new Rectangle(0, 0, 50, 50));
for(int x=0;x<bufferedImage.getWidth();x++)
{
for(int y=0;y<bufferedImage.getWidth();y++)
{
robot.getPixelColor(x, y);
}
}
long nowTime2=System.currentTimeMillis();
<strong> </strong>System.out.println("使用了"+(nowTime2-nowTime)+"毫秒,平均获得一个像素消耗"+((nowTime2-nowTime)/(bufferedImage.getWidth()*bufferedImage.getHeight()))+"毫秒");
} catch (AWTException e) {
// TODO Auto-generated catch block
e.printStackTrace();
<strong> }
}</strong>
这里只截图了一个50*50的极其小的图片,然后对其进行遍历获得像素点的RGB值。最后输出结果竟然是
使用了3362毫秒,平均获得一个像素消耗33毫秒
一个像素消耗了33毫秒!用这种速度找图,不还得找到猴年马月去啊!
后来我就思考为什么会这样,按理来说,获取一个像素的RGB值不应该消耗这么久的时间
我首先换了一个方法,即把robot.getPixelColor(x, y);换成bufferedImage.getRGB(x, y);
再次进行输出
此时代码为
public static void main(String[] args)
{
try {
Robot robot=new Robot();
long nowTime=System.currentTimeMillis();
BufferedImage bufferedImage=robot.createScreenCapture(new Rectangle(0, 0, 1920, 1024));
for(int x=0;x<bufferedImage.getWidth();x++)
{
for(int y=0;y<bufferedImage.getHeight();y++)
{
bufferedImage.getRGB(x, y);
}
}
long nowTime2=System.currentTimeMillis();
System.out.println("使用了"+(nowTime2-nowTime)+"毫秒,平均获得一个像素消耗"+((nowTime2-nowTime)/(bufferedImage.getWidth()*bufferedImage.getHeight()))+"毫秒");
} catch (AWTException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
这个时候查找的范围是1920*1024比之前不知道大了多少倍
代码输出结果
使用了114毫秒,平均获得一个像素消耗0毫秒
这个结果才比较正常!
那么到底是为什么导致了这两个效果似乎相差不多的方法实际执行速度差了十万八千里呢?
我第一个想到的是是不是因为getPixelColor返回的是一个对象color 而getRgb返回的是一个基元类型int 是不是在这上面出了问题呢?
接下来代码进行试验,直接手动创建1000个color对象
代码如下
public static void main(String[] args)
{
long nowTime=System.currentTimeMillis();
for(int i=0;i<1000;i++)
{
new Color(0);
}
long nowTime2=System.currentTimeMillis();
System.out.println(nowTime2-nowTime);
}
输出执行时间,仅仅79毫秒,可以看出,根本就不是这个问题!
那么问题应该就在getPixelColor这个方法本身上面!他到底是怎么实现获取像素点对应的color对象的呢?
我感觉他可能是在每次获取像素点的时候都重新进行了截图,最后进行测试,发现果然如此!
其实想想也可以明白,getRGB操作的对象是一个不会变的内存中的图片。而getPixelColor却是获取当前屏幕上某坐标点的color对象!那么他获取之前,就应该要获取一次整个屏幕的图像吧!所以getPixelColor就变得很慢了!
所以最好的做法还是自己手动把整个屏幕一次截图成bufferedImage,然后再调用getRgb()
----------
欢迎关注我的github https://github.com/luckyCatMiao