diff --git a/ruoyi-modules/Sis/pom.xml b/ruoyi-modules/Sis/pom.xml
index 9cdc13cc..32ca6297 100644
--- a/ruoyi-modules/Sis/pom.xml
+++ b/ruoyi-modules/Sis/pom.xml
@@ -140,6 +140,12 @@
3.0.0
+
+ com.drewnoakes
+ metadata-extractor
+ 2.18.0
+
+
net.java.dev.jna
jna
diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/e8/utils/ImageUtil.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/e8/utils/ImageUtil.java
index 4efff0a4..a209bd81 100644
--- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/e8/utils/ImageUtil.java
+++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/e8/utils/ImageUtil.java
@@ -1,17 +1,21 @@
package org.dromara.sis.sdk.e8.utils;
+import com.drew.imaging.ImageMetadataReader;
+import com.drew.imaging.ImageProcessingException;
+import com.drew.metadata.Metadata;
+import com.drew.metadata.MetadataException;
+import com.drew.metadata.exif.ExifIFD0Directory;
import org.springframework.stereotype.Component;
-import javax.imageio.IIOImage;
-import javax.imageio.ImageIO;
-import javax.imageio.ImageWriteParam;
-import javax.imageio.ImageWriter;
+import javax.imageio.*;
+import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.MemoryCacheImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.util.Iterator;
/**
* @author lsm
@@ -22,7 +26,8 @@ import java.io.IOException;
public class ImageUtil {
public byte[] compressImageToRequirements(byte[] imageData) throws IOException {
- BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageData));
+ // 读取图片并处理方向
+ BufferedImage image = readAndFixOrientation(imageData);
// 第一步:调整分辨率(不超过1000x1000)
if (image.getWidth() > 1000 || image.getHeight() > 1000) {
@@ -91,6 +96,124 @@ public class ImageUtil {
return resizedImage;
}
+ /**
+ * 读取图片并处理 EXIF 方向信息
+ */
+ private BufferedImage readAndFixOrientation(byte[] imageData) throws IOException {
+ try {
+ // 使用 metadata-extractor 读取 EXIF 方向信息
+ Metadata metadata = ImageMetadataReader.readMetadata(new ByteArrayInputStream(imageData));
+ ExifIFD0Directory directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
+
+ int orientation = 1; // 默认正常方向
+ if (directory != null && directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) {
+ orientation = directory.getInt(ExifIFD0Directory.TAG_ORIENTATION);
+ }
+
+ // 读取图片
+ ImageInputStream input = ImageIO.createImageInputStream(new ByteArrayInputStream(imageData));
+ Iterator readers = ImageIO.getImageReaders(input);
+
+ if (!readers.hasNext()) {
+ throw new IOException("No ImageReader found for image data");
+ }
+
+ ImageReader reader = readers.next();
+ reader.setInput(input);
+ BufferedImage image = reader.read(0);
+ reader.dispose();
+
+ // 根据方向信息旋转图片
+ return rotateImageAccordingToOrientation(image, orientation);
+ } catch (ImageProcessingException e) {
+ throw new IOException("Failed to process image metadata", e);
+ } catch (MetadataException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * 根据方向信息旋转图片
+ */
+ private BufferedImage rotateImageAccordingToOrientation(BufferedImage image, int orientation) {
+ int width = image.getWidth();
+ int height = image.getHeight();
+
+ return switch (orientation) {
+ case 1 -> // 正常
+ image;
+ case 2 -> // 水平翻转
+ flipImage(image, true, false);
+ case 3 -> // 旋转180度
+ rotateImage(image, 180);
+ case 4 -> // 垂直翻转
+ flipImage(image, false, true);
+ case 5 -> {
+ image = flipImage(image, true, false);
+ yield rotateImage(image, 270);
+ }
+ case 6 -> // 旋转90度
+ rotateImage(image, 90);
+ case 7 -> {
+ image = flipImage(image, true, false);
+ yield rotateImage(image, 90);
+ }
+ case 8 -> // 旋转270度
+ rotateImage(image, 270);
+ default -> image;
+ };
+ }
+
+ /**
+ * 旋转图片
+ */
+ private BufferedImage rotateImage(BufferedImage image, double degrees) {
+ double radians = Math.toRadians(degrees);
+ double sin = Math.abs(Math.sin(radians));
+ double cos = Math.abs(Math.cos(radians));
+
+ int width = image.getWidth();
+ int height = image.getHeight();
+
+ int newWidth = (int) Math.floor(width * cos + height * sin);
+ int newHeight = (int) Math.floor(height * cos + width * sin);
+
+ BufferedImage rotated = new BufferedImage(newWidth, newHeight, image.getType());
+ Graphics2D g = rotated.createGraphics();
+
+ g.translate((newWidth - width) / 2, (newHeight - height) / 2);
+ g.rotate(Math.toRadians(degrees), width / 2.0, height / 2.0);
+ g.drawRenderedImage(image, null);
+ g.dispose();
+
+ return rotated;
+ }
+
+ /**
+ * 翻转图片
+ */
+ private BufferedImage flipImage(BufferedImage image, boolean horizontal, boolean vertical) {
+ int width = image.getWidth();
+ int height = image.getHeight();
+
+ BufferedImage flipped = new BufferedImage(width, height, image.getType());
+ Graphics2D g = flipped.createGraphics();
+
+ if (horizontal && vertical) {
+ g.drawImage(image, width, height, -width, -height, null);
+ } else if (horizontal) {
+ g.drawImage(image, width, 0, -width, height, null);
+ } else if (vertical) {
+ g.drawImage(image, 0, height, width, -height, null);
+ } else {
+ g.drawImage(image, 0, 0, null);
+ }
+
+ g.dispose();
+ return flipped;
+ }
+
+
private byte[] compressWithQuality(BufferedImage image, float quality) throws IOException {
// 获取JPEG编码器
ImageWriter writer = ImageIO.getImageWritersByFormatName("jpeg").next();