我正在尝试在selenium中编写一个java代码来比较预期和实际的屏幕截图。我创建了两个文件夹
现在我正在尝试比较这些屏幕截图,以确定它们是否匹配。以下是我基本上重新搜索和编写的以下代码段。虽然它是从单个文件夹中读取文件,但比较失败。请指教 ?感谢
public class ImageComparison {
static String workingDir = System.getProperty("user.dir");
static String COMBINATION = "combine";
static String SUBTRACTION = "subtraction";
static String IMAGE_FILE_TYPE = "png";
public static File listFilesForFolder(final File folder) {
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
listFilesForFolder(fileEntry);
} else {
System.out.println(fileEntry.getName());
}
}
return folder;
}
final static File folderActual = new File(workingDir+ "\\ICScreenshots\\");
final static File folderExpected = new File(workingDir+ "\\Screenshots\\");
static File fActual = listFilesForFolder(folderActual);
static File fExpected = listFilesForFolder(folderExpected);
public static void main(String[] args) throws IOException {
BufferedImage imgA = ImageIO.read(new File(fActual + "." + IMAGE_FILE_TYPE));
BufferedImage imgB = ImageIO.read(new File(fExpected + "." + IMAGE_FILE_TYPE));
System.out.println(ImageComparison.bufferedImagesEqual(imgA, imgB));
ImageComparison.subtractImages(imgA, imgB);
ImageComparison.combineImages(imgA, imgB);
}
private static void combineImages(BufferedImage image1, BufferedImage image2) throws IOException {
BufferedImage result = new BufferedImage(image1.getWidth(), image1.getHeight(), image1.getType());
for (int x = 0; x < image1.getWidth(); x++)
for (int y = 0; y < image1.getHeight(); y++) {
result.setRGB(x, y, Math.abs(image2.getRGB(x, y) + image1.getRGB(x, y)));
}
ImageIO.write(result, IMAGE_FILE_TYPE, new File(COMBINATION + "." + IMAGE_FILE_TYPE));
}
private static void subtractImages(BufferedImage image1, BufferedImage image2) throws IOException {
BufferedImage result = new BufferedImage(image1.getWidth(), image1.getHeight(), image1.getType());
for (int x = 0; x < image1.getWidth(); x++)
for (int y = 0; y < image1.getHeight(); y++) {
result.setRGB(x, y, Math.abs(image2.getRGB(x, y) - image1.getRGB(x, y)));
}
ImageIO.write(result, IMAGE_FILE_TYPE, new File(SUBTRACTION + "." + IMAGE_FILE_TYPE));
}
private static boolean bufferedImagesEqual(BufferedImage img1, BufferedImage img2) {
if (!(img1.getWidth() == img2.getWidth() && img1.getHeight() == img2.getHeight())) {
return false;
}
for (int x = 0; x < img1.getWidth(); x++) {
for (int y = 0; y < img1.getHeight(); y++) {
if (img1.getRGB(x, y) != img2.getRGB(x, y))
return false;
}
}
return true;
}
}
我收到以下错误
Exception in thread "main" javax.imageio.IIOException: Can't read input file!
at javax.imageio.ImageIO.read(Unknown Source)
at fin.bi.test.ImageComparison.main(ImageComparison.java:36)
答案 0 :(得分:1)
我假设你对编码有些陌生,所以我要列出不同的问题以及我为解决这些问题所做的工作,这是一项有希望的教育活动。
listFilesForFolder()
设置为向下导航到子文件夹,但您说您不需要它。它返回一个File
,但您声明要循环遍历所有文件。它还只返回父文件夹(不是实际文件),这就是您收到错误的原因。您正在构建一个没有文件名的路径,因此它正在抛出,因为预期的文件是一个文件夹。我重写listFilesForFolder()
以返回List<String>
,以便稍后我们可以迭代它。
您错过了循环浏览文件列表的代码。
我更改了输出文件的名称以包含原始文件名。您的代码将重复写入现有文件subtraction.png。它现在输出一个文件,subtraction..png。
我向File outputFile
和combineImages()
添加了一个参数subtractImages()
,以便能够命名输出图像并避免覆盖输出文件。
假设文件夹结构
ICScreenshots\P1.png
ICScreenshots\P2.png
Screenshots\P1.png
Screenshots\P2.png
Screenshots\P3.png
其中P1相同且P2不同
输出看起来像
P1.png:真实的 P2.png:假
P3.png:ICScreenshots目录中不存在
代码在
之下public class ImageComparison2
{
static String workingDir = System.getProperty("user.dir");
static String COMBINATION = "combination";
static String SUBTRACTION = "subtraction";
static String IMAGE_FILE_TYPE = "png";
final static File folderActual = new File(workingDir + "\\ICScreenshots\\");
final static File folderExpected = new File(workingDir + "\\Screenshots\\");
public static List<String> listFilesForFolder(final File folder) throws IOException
{
List<String> files = new ArrayList<String>();
try (Stream<Path> paths = Files.walk(folder.toPath()))
{
paths.filter(Files::isRegularFile).filter(path -> path.toString().endsWith(".png")).map(Path::getFileName)
.forEach(p -> files.add(p.toString()));
}
return files;
}
public static void main(String[] args) throws IOException
{
for (String s : listFilesForFolder(folderExpected))
{
File actualFile = new File(folderActual.getAbsolutePath() + "\\" + s);
File expectedFile = new File(folderExpected.getAbsolutePath() + "\\" + s);
if (actualFile.exists())
{
BufferedImage imgA = ImageIO.read(actualFile);
BufferedImage imgB = ImageIO.read(expectedFile);
boolean same = ImageComparison2.bufferedImagesEqual(imgA, imgB);
System.out.println(s + ": " + same);
if (!same)
{
ImageComparison2.subtractImages(imgA, imgB, new File(COMBINATION + "." + s));
ImageComparison2.combineImages(imgA, imgB, new File(SUBTRACTION + "." + s));
}
}
else
{
System.out.println(s + ": does not exist in the ICScreenshots directory");
}
}
}
private static void combineImages(BufferedImage image1, BufferedImage image2, File outputFile) throws IOException
{
BufferedImage result = new BufferedImage(image1.getWidth(), image1.getHeight(), image1.getType());
for (int x = 0; x < image1.getWidth(); x++)
for (int y = 0; y < image1.getHeight(); y++)
{
result.setRGB(x, y, Math.abs(image2.getRGB(x, y) + image1.getRGB(x, y)));
}
ImageIO.write(result, IMAGE_FILE_TYPE, outputFile);
}
private static void subtractImages(BufferedImage image1, BufferedImage image2, File outputFile) throws IOException
{
BufferedImage result = new BufferedImage(image1.getWidth(), image1.getHeight(), image1.getType());
for (int x = 0; x < image1.getWidth(); x++)
for (int y = 0; y < image1.getHeight(); y++)
{
result.setRGB(x, y, Math.abs(image2.getRGB(x, y) - image1.getRGB(x, y)));
}
ImageIO.write(result, IMAGE_FILE_TYPE, outputFile);
}
private static boolean bufferedImagesEqual(BufferedImage img1, BufferedImage img2)
{
if (!(img1.getWidth() == img2.getWidth() && img1.getHeight() == img2.getHeight()))
{
return false;
}
for (int x = 0; x < img1.getWidth(); x++)
{
for (int y = 0; y < img1.getHeight(); y++)
{
if (img1.getRGB(x, y) != img2.getRGB(x, y))
return false;
}
}
return true;
}
}