解决图片处理后旋转问题

  1. 问题背景:

对于一些图片,经过一些处理,如hutool的ImgUtil.convert()格式转换,或者Thumbnails的压缩裁剪处理,会出现处理后的图片自动旋转了90°。经过一系列测试,这种情况多出现在使用苹果手机拍的照片。

  1. 问题分析:

经多次尝试后,最终发现,图片出现旋转和使用的工具无太大关系,不排查有部分工具存在问题,主要原因是图片本身的属性问题。首先对图片信息进行分析,使用下面的代码,可以打印出图片信息。

解决图片处理后旋转问题_第1张图片

可以在控制台日志中看到下列信息。

解决图片处理后旋转问题_第2张图片

在日志中可以找到这个关键词Orientation,找个这一行

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

会发现这张图片本身内置了旋转的属性,如果出现了这样属性的图片,那么处理后就会旋转。

  1. 解决方案:

首先在处理前判断图片的是否自带了旋转属性,为什么在处理前,因为在处理后,我们发现图片旋转后,对于旋转后的图片已经不带又旋转的信息了,所以需要在处理前,对原图进行判断。如果带有旋转的图片,就手动对图片进行旋转处理,然后再进行其他处理,如果不需要旋转,则直接进行其他处理。可以参考以下代码:

public static void correctImg(MultipartFile srcFile) {
    File outFile = new File(TEMP_FILE_NAME);
    try (FileOutputStream fos = new FileOutputStream(outFile)){
        // 获取偏转角度
        int angle = getAngle(srcFile);
        if (angle != 90 && angle != 270) {
            // todo 不需要旋转,直接处理
        } else {
            // 原始图片缓存
            BufferedImage srcImg = ImageIO.read(srcFile.getInputStream());
 
            // 宽高互换
            // 原始宽度
            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();
 
            // 输出图片
            ImageIO.write(targetImg, "jpg", fos);
            // todo 旋转结束,后续处理
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
 
private static int getAngle(MultipartFile file) throws Exception {
    Metadata metadata = ImageMetadataReader.readMetadata(file.getInputStream());
    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小工具,小众问题,java)