0

我目前正在围绕元数据提取器库开发一个小型包装器,以便能够从 ColdFusion 代码访问 JPEG 上的一些元数据属性。JPEG 数据作为 base64 字符串从 REST 端点进入 ColdFusion。我想将该字符串转换为字节数组并从 JPEG 中读取 Exif 元数据,将原始创建日期作为字符串返回给 ColdFusion。但是,我无法从转换后的字节数组中读取 Exif 块。

我尝试使用 java.utils.Base64 和 javax.xml.bind.DatatypeConverter 进行 base64 转换,但在这两种情况下元数据提取器都找不到 Exif 数据。我在十六进制编辑器中打开了原始源图像,并且存在 Exif 数据。我还尝试在原始图像文件上使用元数据提取器,效果很好,当我打印出目录和标签时,Exif 标头出现了。

这是我用来读取元数据的类的构造函数:

public ImageMetaDataReader(String base64ImageData) throws IOException, ImageProcessingException {
        // create the image object from the provided string data

        byte [] imageBytes = java.util.Base64.getDecoder().decode(base64ImageData);
        javax.xml.bind.DatatypeConverter.parseBase64Binary(lexicalXSDBase64Binary)
        ByteArrayInputStream imageBytesReader = new ByteArrayInputStream(imageBytes);
        fileMetaData = JpegMetadataReader.readMetadata(imageBytesReader);

        imageBytesReader.reset();

        // read the exif data as well
        exifMetaData = ImageMetadataReader.readMetadata(new ByteArrayInputStream(imageBytes), imageBytes.length, FileType.Jpeg);
        return;
    }

我也徒劳地尝试直接使用 ExifReader,但得到了异常,英特尔和摩托罗拉字节顺序之间的区别不清楚。

当我针对原始图像运行代码时,我得到了所有文件头、Exif 数据和所有其他实际存在于 JPEG 数据中的标签。当我按照构造函数中所示的 base64 字符串运行它时,我得到了一些 JPEG 目录、一些 JFIF 目录和一个 Huffman 表目录,仅此而已。

我怀疑在转换过程中的某个地方,考虑到我上面得到的异常,字节顺序被搞砸了,但我不确定该怎么做才能解决它。我能想出的唯一解决方案是将 JPEG 数据写入一个临时文件,然后再将其读回,但如果有更好的可行解决方案,我宁愿不这样做。

4

1 回答 1

0

答案实际上是我最初在测试代码中创建 base64 字符串的方式。起初,我将图像作为 BufferedImage 抓取,然后使用 ImageIO 方法将其读入字节数组。我将测试代码简化为如下所示:

        byte [] fileContent = Files.readAllBytes(new File("duck.jpeg").toPath());
        String base64Image = java.util.Base64.getEncoder().encodeToString(fileContent);

        ImageMetaDataReader reader = new ImageMetaDataReader(base64Image);
        printResult(reader.getImageMetaData(), "imageMetaDataTest()");

现在我得到了所有的元数据。我唯一能想到的是,当我将图像数据读入字节数组时,ImageIO 函数会以某种方式清除/破坏 Exif 数据。

于 2019-04-04T13:16:28.507 回答