【问题标题】:ImageIO.read( ) always rotates my uploaded pictureImageIO.read() 总是旋转我上传的图片
【发布时间】:2013-04-12 18:53:56
【问题描述】:

我想创建一个允许用户将他们的图像上传到服务器的 Web 应用程序。当他们点击发送时,他们的图像将被上传到服务器(多部分)。在保存之前,我想对图像进行一些操作,所以我决定使用..

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

【问题讨论】:

  • 我现在发现了类似的问题,stackoverflow.com/questions/9453367/…。所以,我的问题不是 ImageIO 的错误,而是 ImageIO 无法读取图像细节(EXIF 方向)的 API 规范。谢了。

标签: java image spring-mvc multipartform-data javax.imageio


【解决方案1】:

如果使用移动设备拍摄,ImageIO.read() 无法读取图像的方向。

我使用元数据提取器来读取元数据,我认为这是一个很好的解决方案: 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;
}

(Rotation 是 org.imgscalr.Scalr 框架中的一个类,我使用 ti 旋转图像)。

【讨论】:

  • 这非常有帮助。带有 Scalar 常量的代码也正是我所需要的。
【解决方案2】:

非常有趣的问题...您可以尝试通过检查图像宽度和高度分别大于 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);
}

【讨论】:

  • 谢谢。参加,但我认为我的话和语法让你误解了。现在,我改进了我的问题。
  • 好的……现在很清楚了……很高兴SO有答案,你也找到了:)
猜你喜欢
  • 2018-10-27
  • 2017-05-25
  • 1970-01-01
  • 2012-12-23
  • 1970-01-01
  • 2013-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多