简体   繁体   English

ImageIO.read( ) 总是旋转我上传的图片

[英]ImageIO.read( ) always rotates my uploaded picture

I want to create a web application that allow users to upload their image to the server.我想创建一个 web 应用程序,允许用户将他们的图像上传到服务器。 When they click send, their image will be uploaded to the server (multipart).当他们点击发送时,他们的图像将被上传到服务器(多部分)。 Before saving, I want to make some operation with the image, so I decided to use..在保存之前,我想对图像进行一些操作,所以我决定使用..

ImageIO.read(InputStream) ImageIO.read(输入流)

to get BufferedImage object获取 BufferedImage object

here is the code:这是代码:

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;
}

The problem is when I try to upload a picture that has height more than width such as 3264 x 2448 (height x width), the result always an image that has been rotated (2448 x 3264).问题是当我尝试上传一张高度大于宽度的图片时,例如 3264 x 2448(高 x 宽),结果总是一张旋转过的图片 (2448 x 3264)。

Is there any solution to solve this problem?有什么办法可以解决这个问题吗?

Is this a bug or any defined API specification?这是错误还是任何已定义的 API 规范?

Thx.谢谢。

PS.附言。 sorry for my english:D对不起我的英语:D

ImageIO.read( ) can't read the orientation of the image if it was taken with mobile device. 如果使用移动设备拍摄,ImageIO.read()无法读取图像的方向。

I used metadata-extractor to read metadata, i think it's a good solution: github.com/drewnoakes/metadata-extractor/wiki 我使用元数据提取器来读取元数据,我认为这是一个很好的解决方案: github.com/drewnoakes/metadata-extractor/wiki

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

Read orientation filed in exif directory: 在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;
}

(Rotation is a class from the org.imgscalr.Scalr framework I use ti rotate image). (旋转是org.imgscalr.Scalr框架中的一个类,我使用ti旋转图像)。

Quite interesting issue... you can try to fix it by introducing a check on the image width and height to be larger than 2448 and 3264 respectively and then just swap its width and height 非常有趣的问题...您可以尝试通过引入图像宽度和高度分别大于2448和3264来检查它,然后只需交换它的宽度和高度

Use below piece of code: 使用下面的代码:

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);
}

A little update on Paolo Biavati answer .关于Paolo Biavati回答的一点更新。

I did not find method metadata.getDirectory(ExifIFD0Directory.class) ;我没有找到方法metadata.getDirectory(ExifIFD0Directory.class) instead what is available is metadata.getFirstDirectoryOfType(ExifIFD0Directory.class) .相反,可用的是metadata.getFirstDirectoryOfType(ExifIFD0Directory.class) May be it was in old versions.可能是旧版本。 Now the code goes like this:现在代码是这样的:

    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;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM