#java #metadata-extractor
#java #метаданные-экстрактор
Вопрос:
В настоящее время я разрабатываю небольшую оболочку вокруг библиотеки извлечения метаданных, чтобы иметь доступ к нескольким атрибутам метаданных в формате JPEG из кода ColdFusion. Данные JPEG поступают в ColdFusion с конечной точки REST в виде строки base64. Я хотел преобразовать эту строку в массив байтов и прочитать метаданные Exif из JPEG, вернув исходную дату создания в ColdFusion в виде строки. Однако я не могу прочитать блок Exif из преобразованного массива байтов.
Я пытался использовать оба java.utils.Base64 и javax.xml.bind.DatatypeConverter для преобразования в base64, но в обоих случаях metadata-extractor не может найти данные Exif. Я открыл исходное исходное изображение в шестнадцатеричном редакторе, и данные Exif присутствуют. Я также попытался использовать metadata-extractor для исходного файла изображения, и это сработало нормально, заголовки 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, но получал исключение, неясное различие между порядком байтов Intel и Motorola.
Когда я запускаю код для исходного изображения, я получаю все заголовки файлов, данные Exif и все другие теги, которые фактически присутствуют в данных JPEG. Когда я запускаю его со строкой base64, как показано в конструкторе, я получаю несколько каталогов JPEG, несколько каталогов JFIF и каталог таблицы Хаффмана, больше ничего.
Я подозреваю, что где-то во время преобразования порядок байтов нарушается, учитывая исключение, которое я получил выше, но я не совсем уверен, что делать, чтобы решить это. Единственное решение, которое я могу придумать, это записать данные JPEG во временный файл, а затем прочитать их обратно, но я бы предпочел не делать этого, если есть более работоспособное решение.
Ответ №1:
Ответ на самом деле оказался в том, как я изначально создавал строку 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, когда я считывал данные изображения в массив байтов.