一、背景介绍
在开发给上传图片打水印的时候,发现了一个奇怪的事情。某张图片在上传后发生了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