我在使用java.awt.Robot
时遇到了一些奇怪的行为。如果我用它来拍摄两个屏幕截图,一个是整个屏幕,另一个只是屏幕的一个部分,屏幕的一个部分与原始屏幕截图的一个子图像具有不同的像素,与子图像具有相同的坐标。下面是我的代码:
import java.awt.AWTException;
import java.awt.Dimension;
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;
public class ScreenCapTest {
public static void main(String[] args) throws AWTException, IOException {
// Construct Robot
Robot r = new Robot();
// Get dimensions of screen
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
// Take screenshot
BufferedImage screen = r.createScreenCapture(new Rectangle(0,0, (int)screenSize.getWidth(), (int)screenSize.getHeight()));
// Take screenshot of small section of screen
int x = 5;
int y = 5;
int w = 50;
int h = 50;
BufferedImage subscreen = r.createScreenCapture(new Rectangle(x,y,w,h));
// Create a subimage of the same section of the screen from the original screenshot
BufferedImage subimageOfScreen = screen.getSubimage(x,y,w,h);
// Are they equal?
System.out.println(imgEqual(subimageOfScreen, subscreen));
// Output images for comparison
ImageIO.write(subimageOfScreen, "png", new File("subimage.png"));
ImageIO.write(subscreen, "png", new File("subscreen.png"));
}
public static boolean imgEqual(BufferedImage image1, BufferedImage image2) {
int width;
int height;
boolean imagesEqual = true;
if( image1.getWidth() == ( width = image2.getWidth() ) &&
image1.getHeight() == ( height = image2.getHeight() ) ){
for(int x = 0;imagesEqual == true && x < width; x++){
for(int y = 0;imagesEqual == true && y < height; y++){
if( image1.getRGB(x, y) != image2.getRGB(x, y) ){
imagesEqual = false;
}
}
}
} else {
imagesEqual = false;
}
return imagesEqual;
}
}
字符串
大多数情况下,它会报告false
,这意味着从(5,5)到(5,5,5,5)的完整屏幕截图的子图像与从(5,5)到(5,5,5,5)的屏幕截图不同。奇怪的是,对于x
,y
,w
和h
的某些值,它会打印true
。
下面是一对BufferedImages的示例,代码将其打印为false
。我可以看到它们略有不同,但我不明白为什么会存在这种行为。这是怎么回事?
完整屏幕截图的子图像:x1c 0d1x
屏幕同一部分的屏幕截图:
1条答案
按热度按时间j7dteeu81#
修改你的代码一点。我不喜欢(原始)代码不断地创建一个屏幕图像的子图像来与实际的子图像进行比较。仍然没有帮助找到匹配。
我的下一步是从原始屏幕图像创建子图像。这是一种测试问题是否与逻辑或子图像有关的方法。在这种情况下,子图像匹配。
然后我回去测试两个机器人创建的图像,并注意到具有较小宽度/高度的子图像将匹配。
进一步测试和宽度似乎不会影响子图像的匹配。
然而,我注意到,高度确实造成了一个问题。在我的情况下,高度需要比屏幕的高度小31像素。巧合的是,31像素是我的Windows机器上的屏幕的高度。所以我的想法是,不知何故,当使用机器人的第二个图像没有正确创建。不知道为什么。
下面是我用来测试的代码:
字符串
第一个子图像在不同的测试用例中对我有效。
第二个子图像仅在使用(0,0)作为偏移量时有效。
第三个子图像似乎适用于所有“y”偏移量高达49。
编辑:
使用你的新代码,我尝试自动化测试:
型
我在命令提示符下使用:
java ScreenCapTest3.java
运行代码,得到了true/false的混合结果。然后运行代码:
java ScreenCapTest.java > out.txt
当我看out.txt时,一切都是真的。
所以在我看来,子图像中有一个微妙的变化,因为System.out.println(...)在捕获第二个图像之前显示在屏幕上?
另一个编辑:
创建了一个简单的框架来覆盖桌面。我用左边的按钮和中间的大图像来打破一个空框架的白色空间。
当你点击按钮时,我使用了一个计时器来延迟屏幕捕获过程,以允许按钮被绘制回原始状态。
型