Изменение размера файла изображения с сохранением информации Exif в формате jpg

Я хотел бы скопировать изображения со всеми данными изображения Exif, которые также скопированы.

У меня есть приложение Java, которое считывает jpg в объект изображения, изменяет его размер, а затем записывает объект изображения в файл jpg в другой папке.

Проблема в том, что при этом теряется вся полезная информация об изображении (камера, дата и т. д.). Любые идеи?


person Baruch Atta    schedule 12.06.2012    source источник
comment
Нет, что такое exif? Я никогда не слышал об этом.   -  person Baruch Atta    schedule 12.06.2012
comment
Да - это то, что мне нужно - Википедия: данные Exif встроены в сам файл изображения. Хотя многие современные программы обработки изображений распознают и сохраняют данные Exif при записи измененного изображения, это не относится к большинству старых программ.   -  person Baruch Atta    schedule 12.06.2012
comment
Я нашел drewnoakes.com/code/exif — извлечение метаданных в java. Я попробую этот пакет и дам вам знать ...   -  person Baruch Atta    schedule 12.06.2012
comment
Нет, это только для извлечения/чтения. Теперь я нашел это: пакет org.apache.sanselan   -  person Baruch Atta    schedule 12.06.2012


Ответы (2)


Хотя это решение предназначено для Android, оно реализовано на Java и должно быть полезно для копирования всех метаданных EXIF ​​из одного файла в другой:

http://bricolsoftconsulting.com/copying-exif-metadata-using-sanselan/

Обратите внимание, что Sanselan недавно был переименован в Commons Imaging, и его можно найти здесь:

http://commons.apache.org/imaging/

person Theo    schedule 09.12.2012

Один из вариантов — использовать ввод-вывод изображения следующим образом:

try (ImageInputStream inputStream = new FileImageInputStream(new File("Landscape_3.jpg"))) {
        Iterator<ImageReader> readerIterator = ImageIO.getImageReaders(inputStream);
        ImageReader reader = readerIterator.next();
        reader.setInput(inputStream);
        Iterator<IIOImage> imageIterator = reader.readAll(null);
        IIOImage image = imageIterator.next();

        BufferedImage srcImage = (BufferedImage) image.getRenderedImage();
        AffineTransformOp scaleOp = new AffineTransformOp(AffineTransform.getScaleInstance(0.5, 0.5), AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
        BufferedImage resultImage = scaleOp.createCompatibleDestImage(srcImage, null);
        resultImage = scaleOp.filter(srcImage, resultImage);
        image.setRenderedImage(resultImage);

        ImageWriter writer = ImageIO.getImageWriter(reader);
        try (ImageOutputStream outputStream = new FileImageOutputStream(new File("Landscape_3_preserve_exif.jpg"))) {
            writer.setOutput(outputStream);
            writer.write(image);
        }
        try (ImageOutputStream outputStream = new FileImageOutputStream(new File("Landscape_3_discard_exif.jpg"))) {
            writer.setOutput(outputStream);
            writer.write(image.getRenderedImage());
        }
    }

Подводные камни:

  • Он медленный, как фреймворк image io в целом.
  • Это необъяснимо терпит неудачу для некоторых редких изображений. Пример (javax.imageio.IIOException: не файл JPEG: начинается с 0xff 0xe2)
  • Это требует использования одной и той же цветовой модели для исходного и целевого изображений. В результате вы не можете использовать билинейную или бикубическую интерполяцию.
person Dmytro Voloshyn    schedule 28.10.2015