javax.imageio - Java 9 ImageIO read\write 给出了与 Java 8 不同的结果

标签 javax.imageio java-9

以下测试在 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/

相关文章:

java - 在数组Java中加载图像

java - Java 中 lambda () -> { } 的含义

Java 9 替换 Class.newInstance

java - 如何使用 Java 9 流接口(interface)/将它们包含在 Java 9 中有什么意义?

java - 从 imageReader 写回修改后的图像

java - 更改 Java ImageIO 类的功能

java - 如何使用 Marvin java 库(或任何其他免费库)附加 2 个大图像?

java - 使用 Java 将 PNG 转换为 JPG 时出现问题 (ImageIO.write())

java - 如何在 Java8 项目中使用 Http Client API(自 Java 9 起)

java.lang.IllegalAccessError : cannot access class because module does not export to unnamed module