解决图片处理后旋转问题

解决图片处理后旋转问题

问题背景:

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

问题分析:

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

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

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

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

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

解决方案:

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

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