Java 对图片进行上传或下载后发生了90度的旋转

一、背景介绍

在开发给上传图片打水印的时候,发现了一个奇怪的事情。某张图片在上传后发生了90度的旋转,但是在window打开来是竖的,上传后在打开就是横的。后来上网查询是由于手机在拍摄时候是横着拍的,在图片处理时将旋转角度存储在了exif信息中,但是用Java方法读取图片会忽略旋转角度,导致了这个问题,而window图片预览、手机图片查看等都会根据旋转角度进行调整,所以是没有问题的。

二、获取旋转角度

那么我们如何才能获取到图片真实的旋转角度呢,这里就需要依赖一个第三方jar包:metadata-extractor,我们可以通过这个jar包获取到照片中包含的EXIF信息,在其中就有着我们需要的旋转角度。

使用到的jar包:

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

打印出EXIF信息:

// 遍历打印图片文件的EXIF信息
private static void printExif(File file) throws ImageProcessingException, IOException {
    Metadata metadata = ImageMetadataReader.readMetadata(file);
    for (Directory directory : metadata.getDirectories()) {
        for (Tag tag : directory.getTags()) {
            System.out.println(tag + " = " + tag.getDescription());
        }
    }
}

下面是打印出的EXIF内容
在这里插入图片描述

我们可以看到在打印出的信息中有这么一行信息,这行信息中的Rotate 90 CW就表示这张照片的旋转角度是90度。

[Exif IFD0] Orientation - Right side, top (Rotate 90 CW) = Right side, top (Rotate 90 CW)

那不同的拍照角度分别对应着什么标识符呢,下面是我从网上找来的大神的实验结果,以供参考:

  • 横拿手机右手拍照,照片方向"1"“Horizontal”。
  • 正常拿手机竖拍,照片方向"6"“Rotate 90 CW”,图片顺时针旋转90度时,即正常。
  • 再转90度,横拿,左手拍照,照片方向"3"“Rotate 180”,旋转180度即可正常显示方向。
  • 再转90度,手机头朝下拍,照片方向"8"“Rotate 270 CW”。

三、纠正图片

在上面我们获取到了图片的旋转角度后,我们就可以通过下面的代码从而获取旋转后的图片了。

/**
 * 纠正图片旋转
 *
 * @param srcImgPath
 */
public static void correctImg(String srcImgPath) {
    FileOutputStream fos = null;
    try {
        // 原始图片
        File srcFile = new File(srcImgPath);

        // 获取偏转角度
        int angle = getAngle(srcFile);
        if (angle != 90 && angle != 270) {
            return;
        }

        // 原始图片缓存
        BufferedImage srcImg = ImageIO.read(srcFile);

        // 宽高互换
        // 原始宽度
        int imgWidth = srcImg.getHeight();
        // 原始高度
        int imgHeight = srcImg.getWidth();

        // 中心点位置
        double centerWidth = ((double) imgWidth) / 2;
        double centerHeight = ((double) imgHeight) / 2;

        // 图片缓存
        BufferedImage targetImg = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);

        // 旋转对应角度
        Graphics2D g = targetImg.createGraphics();
        g.rotate(Math.toRadians(angle), centerWidth, centerHeight);
        g.drawImage(srcImg, (imgWidth - srcImg.getWidth()) / 2, (imgHeight - srcImg.getHeight()) / 2, null);
        g.rotate(Math.toRadians(-angle), centerWidth, centerHeight);
        g.dispose();

        // 输出图片
        fos = new FileOutputStream(srcFile);
        ImageIO.write(targetImg, "jpg", fos);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (fos != null) {
            try {
                fos.flush();
                fos.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

/**
 * 获取图片旋转角度
 *
 * @param file 上传图片
 * @return
 */
private static int getAngle(File file) throws Exception {
    Metadata metadata = ImageMetadataReader.readMetadata(file);
    for (Directory directory : metadata.getDirectories()) {
        for (Tag tag : directory.getTags()) {
            if ("Orientation".equals(tag.getTagName())) {
                String orientation = tag.getDescription();
                if (orientation.contains("90")) {
                    return 90;
                } else if (orientation.contains("180")) {
                    return 180;
                } else if (orientation.contains("270")) {
                    return 270;
                }
            }
        }
    }
    return 0;
}

转载自:https://blog.csdn.net/yuyu1067/article/details/116333935

Java中,图片上传后可能会自动进行旋转,这是因为图片的Exif信息中包含了旋转信息。解决办法可以通过以下步骤实现: 1.读取图片的Exif信息,获取旋转角度值。 2.根据旋转角度值对图片进行旋转。 3.保存旋转后的图片。 以下是示例代码: ```java //读取图片的Exif信息 Metadata metadata = ImageMetadataReader.readMetadata(inputStream); Directory directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class); int orientation = 1; if (directory != null && directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) { orientation = directory.getInt(ExifIFD0Directory.TAG_ORIENTATION); } //根据旋转角度值对图片进行旋转 BufferedImage bufferedImage = ImageIO.read(inputStream); if (orientation == 6) { bufferedImage = rotateImage(bufferedImage, 90); } else if (orientation == 3) { bufferedImage = rotateImage(bufferedImage, 180); } else if (orientation == 8) { bufferedImage = rotateImage(bufferedImage, 270); } //保存旋转后的图片 ImageIO.write(bufferedImage, "jpg", outputStream); ``` 其中,rotateImage为自定义函数,用于旋转图片,示例代码如下: ```java public static BufferedImage rotateImage(BufferedImage bufferedimage, int degree) { int w = bufferedimage.getWidth(); int h = bufferedimage.getHeight(); int type = bufferedimage.getColorModel().getTransparency(); BufferedImage img; Graphics2D graphics2d; (graphics2d = (img = new BufferedImage(w, h, type)).createGraphics()).setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); graphics2d.rotate(Math.toRadians(degree), w / 2, h / 2); graphics2d.drawImage(bufferedimage, 0, 0, null); graphics2d.dispose(); return img; } ``` 这样就可以解决Java上传图片后自动旋转的问题了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值