ImageIO.read() всегда поворачивает загруженное изображение

Я хочу создать веб-приложение, которое позволит пользователям загружать свое изображение на сервер. Когда они нажмут «Отправить», их изображение будет загружено на сервер (многочастное). Перед сохранением я хочу произвести некоторую операцию с изображением, поэтому решил использовать ..

ImageIO.read (входной поток)

чтобы получить объект BufferedImage

вот код:

public static BufferedImage getBufferedImageFromMultipartFile(MultipartFile file) 
throws APIException
{
    BufferedImage bi = null;

    try
    {
        bi = ImageIO.read(file.getInputStream());
    }
    catch (IOException e)
    {
        throw new APIException(ErrorCode.SERVER_ERROR, e);
    }

    return bi;
}

Проблема заключается в том, что когда я пытаюсь загрузить изображение, высота которого больше ширины, например 3264 x 2448 (высота x ширина), в результате всегда получается повернутое изображение (2448 x 3264).

Есть ли какое-нибудь решение для решения этой проблемы?

Это ошибка или какая-то определенная спецификация API?

Спасибо.

PS. извините за мой английский :D


person kp_ping    schedule 12.04.2013    source источник
comment
Я нашел аналогичный вопрос сейчас, stackoverflow.com/questions/9453367/. Итак, моя проблема не в том, что ошибка ImageIO, а в спецификации API, что ImageIO не может читать детали изображения (EXIF-ориентация). СПАСИБО.   -  person kp_ping    schedule 12.04.2013


Ответы (2)


ImageIO.read() не может прочитать ориентацию изображения, если оно было снято мобильным устройством.

Я использовал metadata-extractor для чтения метаданных, я думаю, что это хорошее решение: github.com/drewnoakes/metadata -extractor/вики

<dependency> 
  <groupId>com.drewnoakes</groupId> 
  <artifactId>metadata-extractor</artifactId> 
  <version>2.7.2</version> 
</dependency>

Чтение ориентации в каталоге exif:

ExifIFD0Directory exifIFD0 = metadata.getDirectory(ExifIFD0Directory.class);
int orientation = exifIFD0.getInt(ExifIFD0Directory.TAG_ORIENTATION);

switch (orientation) {
  case 1: // [Exif IFD0] Orientation - Top, left side (Horizontal / normal)
    return null;
  case 6: // [Exif IFD0] Orientation - Right side, top (Rotate 90 CW)
    return Rotation.CW_90;
  case 3: // [Exif IFD0] Orientation - Bottom, right side (Rotate 180)
    return Rotation.CW_180;
  case 8: // [Exif IFD0] Orientation - Left side, bottom (Rotate 270 CW)
    return Rotation.CW_270;
}

(Вращение — это класс из фреймворка org.imgscalr.Scalr, который я использую для поворота изображения).

person Paolo Biavati    schedule 28.03.2015
comment
Это было чрезвычайно полезно. Код с константами Scalr тоже оказался именно тем, что мне было нужно. - person Bill; 11.05.2015

Довольно интересная проблема... можно попытаться исправить, введя проверку на то, чтобы ширина и высота изображения были больше 2448 и 3264 соответственно, а затем просто поменять местами ширину и высоту

Используйте приведенный ниже фрагмент кода:

BufferedImage oldImage = ImageIO.read(file.getInputStream());

if (oldImage.getWidth() > 2448 || oldImage.getHeight() > 3264) {

    BufferedImage newImage = new BufferedImage(oldImage.getWidth(),
                oldImage.getHeight(), oldImage.getType());

    Graphics2D graphics = (Graphics2D) newImage.getGraphics();

    graphics.drawImage(oldImage, 0, 0, oldImage.getHeight(),
                oldImage.getWidth(), null);

    ByteArrayOutputStream bos = new ByteArrayOutputStream();

    ImageIO.write(newImage, "JPG", bos);
}
person Bond - Java Bond    schedule 12.04.2013
comment
Спасибо. для участия, но я думаю, что мои слова и грамматика вызывают у вас недопонимание. Теперь я улучшил свой вопрос. - person kp_ping; 12.04.2013
comment
хорошо ... теперь все ясно ... хорошо, что у ТАК есть ответ, и вы тоже его нашли :) - person Bond - Java Bond; 12.04.2013