diff --git a/pom.xml b/pom.xml
index 98e740b..60c8b26 100644
--- a/pom.xml
+++ b/pom.xml
@@ -64,6 +64,12 @@
thumbnailator
0.4.20
+
+ com.drewnoakes
+ metadata-extractor
+ 2.19.0
+
+
com.jjb.saas
jjb-saas-system-client
diff --git a/web-domain/pom.xml b/web-domain/pom.xml
index 29907b3..edbf291 100644
--- a/web-domain/pom.xml
+++ b/web-domain/pom.xml
@@ -22,5 +22,9 @@
com.jjb.saas
jjb-saas-base-starter
+
+ com.drewnoakes
+ metadata-extractor
+
diff --git a/web-domain/src/main/java/com/zcloud/edu/domain/utils/ImageUtil.java b/web-domain/src/main/java/com/zcloud/edu/domain/utils/ImageUtil.java
index e89087f..47d1016 100644
--- a/web-domain/src/main/java/com/zcloud/edu/domain/utils/ImageUtil.java
+++ b/web-domain/src/main/java/com/zcloud/edu/domain/utils/ImageUtil.java
@@ -9,26 +9,37 @@ import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.net.URL;
-import net.coobird.thumbnailator.Thumbnails;
-import net.coobird.thumbnailator.geometry.Positions;
+import com.drew.imaging.ImageMetadataReader;
+import com.drew.metadata.Metadata;
+import com.drew.metadata.exif.ExifIFD0Directory;
public class ImageUtil {
public static PictureRenderData createWithThumbnailator(String imageUrl, int width, int height) {
try {
// 下载原图
URL url = new URL(imageUrl);
- BufferedImage original = ImageIO.read(url);
+ BufferedImage originalImage = ImageIO.read(url);
- // 使用Thumbnailator处理 - 一行代码搞定旋转和缩放
- BufferedImage processed = Thumbnails.of(original)
- .size(width, height)
- .rotate(270) // 如果需要固定旋转,可以直接指定
- .asBufferedImage();
+ // 1. 读取EXIF判断是否需要旋转
+ int rotationAngle = getRotationAngleFromExif(url);
- // 或者使用EXIF自动旋转(如果Thumbnailator版本支持)
- // Thumbnails.of(original).scale(1.0).useExifOrientation().asBufferedImage();
+ // 2. 根据判断结果决定是否旋转
+ BufferedImage processedImage;
+ if (rotationAngle != 0) {
+ // 需要旋转
+ processedImage = Thumbnails.of(originalImage)
+ .size(width, height)
+ .rotate(rotationAngle)
+ .asBufferedImage();
+ } else {
+ // 不需要旋转,只缩放
+ processedImage = Thumbnails.of(originalImage)
+ .size(width, height)
+ .asBufferedImage();
+ }
+ // 3. 转换为byte数组
ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ImageIO.write(processed, "jpg", baos);
+ ImageIO.write(processedImage, "jpg", baos);
return Pictures.ofBytes(baos.toByteArray(), PictureType.JPEG)
.size(width, height)
@@ -40,4 +51,33 @@ public class ImageUtil {
.create();
}
}
+ /**
+ * 从EXIF读取需要旋转的角度
+ * 返回:0-不需要旋转,90/180/270-需要旋转的角度
+ */
+ private static int getRotationAngleFromExif(URL url) {
+ try {
+ Metadata metadata = ImageMetadataReader.readMetadata(url.openStream());
+ ExifIFD0Directory exifDir = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
+
+ if (exifDir != null && exifDir.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) {
+ int orientation = exifDir.getInt(ExifIFD0Directory.TAG_ORIENTATION);
+
+ // 根据Orientation值返回需要的旋转角度 [citation:9]
+ switch (orientation) {
+ case 3: // 需要旋转180度
+ return 180;
+ case 6: // 需要顺时针旋转90度(最常见:手机竖拍)
+ return 90;
+ case 8: // 需要逆时针旋转90度
+ return 270;
+ default: // 1或其他,不需要旋转
+ return 0;
+ }
+ }
+ } catch (Exception e) {
+ // 忽略EXIF读取错误,返回0表示不旋转
+ }
+ return 0;
+ }
}