问题背景:
对于一些图片,经过一些处理,如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