以下测试在 Java 9 上失败,而在 Java 8 中通过:
@Test
public void getImage_SetValueUsingConstructor_ShouldReturnCorrectValue() throws Exception {
String base64ImageString = "iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAEUlEQVR42mNgQAP/wQAbBw4ANwsL9Zo6V30AAAAASUVORK5CYII=";
byte[] rawImageBytes = Base64.getDecoder().decode(base64ImageString);
ByteArrayInputStream bis = new ByteArrayInputStream(rawImageBytes);
RenderedImage image = ImageIO.read(bis);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ImageIO.write(image, "PNG", bos);
byte[] imageBytesFromImage = bos.toByteArray();
assertArrayEquals(imageBytesFromImage, rawImageBytes);
}
Java 9 输出:
数组首先在元素 [42] 处不同;
预计:94
实际:-38
任何人都可以帮助我了解 Java 9 中的更改,有没有办法编写此代码以便它适用于 Java 8 和 9?
最佳答案
正如@Holger 在评论中指出的那样,确实是测试存在缺陷。虽然相同的 Base64 表示会给出相同的图像,但不同的 Base64 表示并不意味着图像数据不同。这可能仅意味着相同的图像数据以不同的方式编码,并将解码为完全相同的图像(这里就是这种情况)。
您的测试过去没有错误通过的原因可能是您使用了 Java 8 PNGImageWriter
(或更早,它自 Java 1.4 以来并没有真正改变),如果你这样做了,它是使用的 writer 插件 ImageIO.write(image, "PNG", output)
, 对图像进行编码并从中创建 Base64 表示。如果您从由不同程序/库创建的文件中创建了字节的 Base64 表示,则几乎肯定会有所不同。
您应该重写您的测试,但是我不太清楚您要在这里测试什么。
如果您只关心像素数据,则可以循环遍历像素并测试是否相等:
BufferedImage original = ImageIO.read(..);
BufferedImage current = ImageIO.read(..);
assertEquals(original.getWidth(), current.getWidth());
assertEquals(original.getHeight(), current.getHeight());
for (int y = 0; y < original.getHeight(); y++) {
for (int x = 0; x < original.getWidth(); x++) {
assertEquals(original.getRGB(x, y), current.getRGB(x, y));
}
}
如果您还需要保留元数据,您还需要在那里测试是否相等。但是 PNG 并没有真正包含很多有趣的元数据,所以我怀疑您是否需要它。
关于javax.imageio - Java 9 ImageIO read\write 给出了与 Java 8 不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46790556/