Java Base64编码的图像与保存的图像不同

Java Base64编码的图像与保存的图像不同,java,Java,我使用ImageIO将Base64图像字符串保存到文件中: public static String decodeBase64AndSaveImage(String data) throws IOException, BadRequestException { try { if (data == null) { return null; } String base64Image = data.split(",")[1

我使用
ImageIO
Base64
图像字符串保存到文件中:

public static String decodeBase64AndSaveImage(String data) throws IOException, BadRequestException {
    try {
        if (data == null) {
            return null;
        }
        String base64Image = data.split(",")[1];
        byte[] imageBytes = DatatypeConverter.parseBase64Binary(base64Image);
        BufferedImage img = ImageIO.read(new ByteArrayInputStream(imageBytes));
        String imageId = generateRandomKey(15);
        ImageIO.write(img, "png", getImageFile(imageId));
        return imageId;
    } catch (IllegalArgumentException e) {
        throw new BadRequestException("Bad image data");
    }
}
我将以下字符串传递给此方法:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAADklEQVQIW2NgQAXGZHAAGioAza6+Hk0AAAAASUVORK5CYII=
在以下测试中,我检查保存到文件的内容是否与传递到方法的内容相同:

        byte[] base64ImageData = Base64.encodeBase64(FileUtils.readFileToByteArray(imageFile));
        Assert.assertEquals("wrong image data stored", DUMMY_IMAGE
                .split(",")[1], new String(base64ImageData,
                StandardCharsets.UTF_8));
但它返回一个不同的字符串:

iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAADklEQVR42mNgQAXGZHAAGioAzTktUZoAAAAASUVORK5CYII=
为什么会发生这种情况

注1


它不比较
数据:image/png;base64,
所以这不是它失败的原因

您正在对字符串进行base64解码,使用ImageIO创建BuffereImage,将其转换回PNG,然后对该结果重新进行base64编码

byte[] imageBytes = DatatypeConverter.parseBase64Binary(base64Image);
BufferedImage img = ImageIO.read(new 
   ByteArrayInputStream(imageBytes));
String imageId = generateRandomKey(15);

// re-encode
ImageIO.write(img, "png", getImageFile(imageId));
这一切都很好。但图像编码器对图像的编码方式与原始图像略有不同。它们都是有效的PNG文件和有效的base64字符串


我对这两个字符串进行了解码,发现它们生成的有效PNG文件看起来相同,但编码方式不同。

您正在对字符串进行base64解码,使用ImageIO创建BuffereImage,将其转换回PNG,然后重新对该结果进行base64编码

byte[] imageBytes = DatatypeConverter.parseBase64Binary(base64Image);
BufferedImage img = ImageIO.read(new 
   ByteArrayInputStream(imageBytes));
String imageId = generateRandomKey(15);

// re-encode
ImageIO.write(img, "png", getImageFile(imageId));
这一切都很好。但图像编码器对图像的编码方式与原始图像略有不同。它们都是有效的PNG文件和有效的base64字符串


我对这两个字符串进行了解码,发现它们生成的有效PNG文件看起来相同,但编码方式不同。

如果使用命令行base64编码/解码程序转储文件内容,会发生什么情况?该问题是在读操作还是写操作中引入的?这里真的有问题吗?第二个base64字符串是否生成不同的图像?您是否在调试器中单步执行程序并将二进制数据与预期数据进行比较?您可以在这里进行很多故障排除,而且您的位置比我们好得多。如果使用命令行base64编码/解码程序转储文件内容,会发生什么情况?该问题是在读操作还是写操作中引入的?这里真的有问题吗?第二个base64字符串是否生成不同的图像?您是否在调试器中单步执行程序并将二进制数据与预期数据进行比较?你可以在这里做很多故障排除,而且你比我们做得更好。有没有一种方法可以用完全相同的方式对图像进行编码?还是说做这样的测试没有意义?我想它一开始不是用ImageIO编码的?不,期望它是100%相同的二进制输出似乎没有意义。您可以比较同一位图的缓冲图像,但您必须问问自己测试的重点和失败的可能性,以及最终是否只是测试代码库,而不是测试自己代码的路径。我将测试“一些二进制”二进制到base64的编码和解码。忽略此测试的PNG数据。然后可能是其他测试,您正在正确地编码/解码PNG。有没有一种方法可以用完全相同的方式对图像进行编码?还是说做这样的测试没有意义?我想它一开始不是用ImageIO编码的?不,期望它是100%相同的二进制输出似乎没有意义。您可以比较同一位图的缓冲图像,但您必须问问自己测试的重点和失败的可能性,以及最终是否只是测试代码库,而不是测试自己代码的路径。我将测试“一些二进制”二进制到base64的编码和解码。忽略此测试的PNG数据。然后可能是其他测试,您正在正确编码/解码PNG。