我正在研究Java应用程序的一部分,该应用程序将图像作为字节数组,将其读入java.awt.image.BufferedImage实例并将其传递给第三方库进行处理.
对于单元测试,我想拍摄一张图像(来自磁盘上的文件)并声明它等于代码处理过的相同图像.
BufferedImage是从磁盘上的PNG文件中读取ImageIO.read(URL).BufferedImage并将其作为PNG写入字节数组,以提供给被测系统.当被测系统将字节数组写入新的时,BufferedImage我想断言两个图像以有意义的方式相等.使用equals()(继承自Object)不起作用(当然).比较BufferedImage.toString()值也不起作用,因为输出字符串包括对象引用信息.
有人知道任何捷径吗?我不想在大型应用程序的一小部分中引入第三方库进行单个单元测试.
Mr.*_*irl 16
这是最好的方法.无需保留变量来判断图像是否仍然相等.如果条件为false,则立即返回false.短路评估有助于在比较失败后节省像素循环时间,就像trumpetlick的回答一样.
/**
* Compares two images pixel by pixel.
*
* @param imgA the first image.
* @param imgB the second image.
* @return whether the images are both the same or not.
*/
public static boolean compareImages(BufferedImage imgA, BufferedImage imgB) {
// The images must be the same size.
if (imgA.getWidth() != imgB.getWidth() || imgA.getHeight() != imgB.getHeight()) {
return false;
}
int width = imgA.getWidth();
int height = imgA.getHeight();
// Loop over every pixel.
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
// Compare the pixels for equality.
if (imgA.getRGB(x, y) != imgB.getRGB(x, y)) {
return false;
}
}
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
如果速度是一个问题,并且两者BufferedImages都具有相同的位深度,排列等(这似乎必须在这里),你可以这样做:
DataBuffer dbActual = myBufferedImage.getRaster().getDataBuffer();
DataBuffer dbExpected = bufferImageReadFromAFile.getRaster().getDataBuffer();
Run Code Online (Sandbox Code Playgroud)
弄清楚它是哪种类型,例如a DataBufferInt
DataBufferInt actualDBAsDBInt = (DataBufferInt) dbActual ;
DataBufferInt expectedDBAsDBInt = (DataBufferInt) dbExpected ;
Run Code Online (Sandbox Code Playgroud)
对DataBuffers的大小和库进行一些"完整性检查",然后循环
for (int bank = 0; bank < actualDBAsDBInt.getNumBanks(); bank++) {
int[] actual = actualDBAsDBInt.getData(bank);
int[] expected = expectedDBAsDBInt.getData(bank);
// this line may vary depending on your test framework
assertTrue(Arrays.equals(actual, expected));
}
Run Code Online (Sandbox Code Playgroud)
由于您一次抓取一大块数据,而不是一次抓取一大块数据,因此速度接近最快.
| 归档时间: |
|
| 查看次数: |
16164 次 |
| 最近记录: |