ImageIO.read() всегда вращает мою загруженную картинку
Я хочу создать веб-приложение, которое позволит пользователям загружать свои изображения на сервер. Когда они нажимают кнопку отправить, их изображение будет загружено на сервер (multipart). Перед сохранением я хочу сделать некоторую операцию с изображением, поэтому я решил использовать..
ImageIO.read (InputStream)
получить объект 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
3 ответа
ImageIO.read() не может прочитать ориентацию изображения, если оно было снято на мобильном устройстве.
Я использовал экстрактор метаданных для чтения метаданных, я думаю, что это хорошее решение: http://github.com/drewnoakes/metadata-extractor/wiki
<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, который я использую для поворота изображения).
Довольно интересная проблема... вы можете попытаться исправить это, введя проверку ширины и высоты изображения, чтобы они были больше 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);
}
Небольшая обновленная информация об Паоло Биавати . ответе
Я не нашел методаmetadata.getDirectory(ExifIFD0Directory.class)
; вместо этого доступно то, что естьmetadata.getFirstDirectoryOfType(ExifIFD0Directory.class)
. Возможно это было в старых версиях. Теперь код выглядит следующим образом:
Metadata metadata = ImageMetadataReader.readMetadata(file);
ExifIFD0Directory exifIFD0 = metadata.getFirstDirectoryOfType(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;
}