From 4aa4a9f3ddeccf7d8f05f54a127f0334b7691aaf Mon Sep 17 00:00:00 2001
From: zqy <2522236926@qq.com>
Date: 星期一, 19 一月 2026 10:59:02 +0800
Subject: [PATCH] 修改缩略图翻转问题

---
 zhang-content/src/main/java/com/ruoyi/service/impl/VideoProcessService.java |  183 ++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 154 insertions(+), 29 deletions(-)

diff --git a/zhang-content/src/main/java/com/ruoyi/service/impl/VideoProcessService.java b/zhang-content/src/main/java/com/ruoyi/service/impl/VideoProcessService.java
index 7dc98db..7e62948 100644
--- a/zhang-content/src/main/java/com/ruoyi/service/impl/VideoProcessService.java
+++ b/zhang-content/src/main/java/com/ruoyi/service/impl/VideoProcessService.java
@@ -1,5 +1,8 @@
 package com.ruoyi.service.impl;
 
+import com.drew.imaging.ImageMetadataReader;
+import com.drew.metadata.Metadata;
+import com.drew.metadata.exif.ExifIFD0Directory;
 import com.ruoyi.common.config.RuoYiConfig;
 import com.ruoyi.common.utils.StringUtils;
 import lombok.extern.slf4j.Slf4j;
@@ -15,6 +18,7 @@
 import javax.imageio.ImageWriter;
 import javax.imageio.stream.MemoryCacheImageOutputStream;
 import java.awt.*;
+import java.awt.geom.AffineTransform;
 import java.awt.image.BufferedImage;
 import java.io.*;
 import java.nio.file.Files;
@@ -68,18 +72,125 @@
 
 
 
+    /**
+     * 璇诲彇鍥剧墖骞跺鐞咵XIF鏂瑰悜
+     */
+    private BufferedImage readImageWithExifOrientation(File file) throws Exception {
+        // 璇诲彇鍘熷鍥剧墖
+        BufferedImage originalImage = ImageIO.read(file);
+        if (originalImage == null) {
+            return null;
+        }
 
+        // 鑾峰彇EXIF鏂瑰悜
+        int orientation = 1;
+        try {
+            orientation = getExifOrientation(file);
+        } catch (Exception e) {
+            // 濡傛灉涓嶈兘璇诲彇EXIF锛屼娇鐢ㄩ粯璁ゆ柟鍚�
+            log.warn("鏃犳硶璇诲彇EXIF鏂瑰悜淇℃伅: {}", e.getMessage());
+        }
+
+        // 鏍规嵁鏂瑰悜鏃嬭浆鍥剧墖
+        return rotateImageByExifOrientation(originalImage, orientation);
+    }
+
+    /**
+     * 鑾峰彇EXIF鏂瑰悜淇℃伅
+     */
+    private int getExifOrientation(File file) throws Exception {
+        Metadata metadata = ImageMetadataReader.readMetadata(file);
+        ExifIFD0Directory exifIFD0Directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
+
+        if (exifIFD0Directory != null && exifIFD0Directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) {
+            return exifIFD0Directory.getInt(ExifIFD0Directory.TAG_ORIENTATION);
+        }
+
+        return 1; // 榛樿鏂瑰悜
+    }
+
+    /**
+     * 鏍规嵁EXIF鏂瑰悜鏃嬭浆鍥剧墖
+     */
+    private BufferedImage rotateImageByExifOrientation(BufferedImage image, int orientation) {
+        int width = image.getWidth();
+        int height = image.getHeight();
+
+        AffineTransform transform = new AffineTransform();
+
+        switch (orientation) {
+            case 1: // 姝e父
+                return image;
+            case 2: // 姘村钩缈昏浆
+                transform.scale(-1, 1);
+                transform.translate(-width, 0);
+                break;
+            case 3: // 鏃嬭浆180搴�
+                transform.translate(width, height);
+                transform.rotate(Math.PI);
+                break;
+            case 4: // 鍨傜洿缈昏浆
+                transform.scale(1, -1);
+                transform.translate(0, -height);
+                break;
+            case 5: // 椤烘椂閽堟棆杞�90搴� + 姘村钩缈昏浆
+                transform.rotate(-Math.PI / 2);
+                transform.scale(-1, 1);
+                break;
+            case 6: // 椤烘椂閽堟棆杞�90搴�
+                transform.rotate(Math.PI / 2);
+                transform.translate(0, -height);
+                break;
+            case 7: // 椤烘椂閽堟棆杞�270搴� + 姘村钩缈昏浆
+                transform.rotate(Math.PI / 2);
+                transform.scale(-1, 1);
+                transform.translate(-width, 0);
+                break;
+            case 8: // 椤烘椂閽堟棆杞�270搴�
+                transform.rotate(-Math.PI / 2);
+                transform.translate(-width, 0);
+                break;
+            default:
+                return image;
+        }
+
+        // 璁$畻鏂板浘鐗囧昂瀵�
+        double newWidth, newHeight;
+        if (orientation >= 5 && orientation <= 8) {
+            // 鏃嬭浆浜�90鎴�270搴︼紝瀹介珮浜掓崲
+            newWidth = height;
+            newHeight = width;
+        } else {
+            newWidth = width;
+            newHeight = height;
+        }
+
+        BufferedImage rotatedImage = new BufferedImage(
+            (int) Math.ceil(newWidth),
+            (int) Math.ceil(newHeight),
+            image.getType()
+        );
+
+        Graphics2D g2d = rotatedImage.createGraphics();
+        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
+            RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+
+        g2d.drawImage(image, transform, null);
+        g2d.dispose();
+
+        return rotatedImage;
+    }
 
 
     /**
      * 澶勭悊鍥剧墖鏂囦欢
      */
     public Map<String, Object> processImage(File file, int width, int height,
-                                            float quality, String format,boolean deleteY) throws IOException {
+                                            float quality, String format) throws Exception {
         Map<String, Object> result = new HashMap<>();
 
         // 璇诲彇鍥剧墖
-        BufferedImage image = ImageIO.read(file);
+        BufferedImage image = readImageWithExifOrientation(file);
         if (image == null) {
             result.put("success", false);
             result.put("message", "鏃犳硶璇诲彇鍥剧墖鏂囦欢");
@@ -108,11 +219,6 @@
         result.put("compressedHeight", height > 0 ? height : originalHeight);
         result.put("base64", dataUrl);
         result.put("message", "鍥剧墖鍘嬬缉鎴愬姛");
-        if (deleteY) {
-            file.delete();
-            result.put("originalDeleted", false);
-            result.put("message", "鍥剧墖鍘嬬缉鎴愬姛");
-        }
         return result;
     }
 
@@ -225,29 +331,57 @@
     }
 
     /**
-     * 鍘嬬缉涓篜NG鏍煎紡
+     * 鍘嬬缉涓篜NG鏍煎紡锛堝吋瀹规�т慨澶嶏級
      */
     private void compressAsPng(BufferedImage image, ByteArrayOutputStream output, int compressionLevel)
         throws IOException {
         Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("png");
         if (!writers.hasNext()) {
-            ImageIO.write(image, "png", output);
+            // 濡傛灉娌℃湁PNG缂栫爜鍣紝浣跨敤榛樿鏂瑰紡
+            boolean written = ImageIO.write(image, "png", output);
+            if (!written) {
+                throw new IOException("鏃犳硶鍐欏叆PNG鏍煎紡");
+            }
             return;
         }
 
         ImageWriter writer = writers.next();
-        ImageWriteParam param = writer.getDefaultWriteParam();
+        try {
+            ImageWriteParam param = writer.getDefaultWriteParam();
 
-        // PNG鐨勫帇缂╃骇鍒紙0-9锛�0鏈�蹇絾鍘嬬缉鐜囦綆锛�9鏈�鎱絾鍘嬬缉鐜囬珮锛�
-        if (compressionLevel >= 0) {
-            param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
-            param.setCompressionType("Deflate");
-            param.setCompressionQuality(Math.max(0.0f, Math.min(1.0f, compressionLevel / 9.0f)));
+            // PNG鐨勫帇缂╃骇鍒紙0-9锛�0鏈�蹇絾鍘嬬缉鐜囦綆锛�9鏈�鎱絾鍘嬬缉鐜囬珮锛�
+            if (compressionLevel >= 0) {
+                try {
+                    // 鍏堟鏌ユ槸鍚︽敮鎸佸帇缂╂ā寮�
+                    if (param.canWriteCompressed()) {
+                        param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+                        // 妫�鏌ユ槸鍚︽敮鎸丏eflate鍘嬬缉绫诲瀷
+                        String[] compressionTypes = param.getCompressionTypes();
+                        if (compressionTypes != null) {
+                            for (String type : compressionTypes) {
+                                if ("Deflate".equalsIgnoreCase(type)) {
+                                    param.setCompressionType("Deflate");
+                                    break;
+                                }
+                            }
+                        }
+                        param.setCompressionQuality(Math.max(0.0f, Math.min(1.0f, compressionLevel / 9.0f)));
+                    } else {
+                        // 濡傛灉涓嶆敮鎸佸帇缂╋紝浣跨敤榛樿璁剧疆
+                        log.debug("PNG缂栫爜鍣ㄤ笉鏀寔鍘嬬缉璁剧疆锛屼娇鐢ㄩ粯璁ゅ帇缂�");
+                    }
+                } catch (UnsupportedOperationException e) {
+                    // 鎹曡幏涓嶆敮鎸佺殑鎿嶄綔寮傚父锛岀户缁娇鐢ㄩ粯璁よ缃�
+                    log.warn("PNG鍘嬬缉璁剧疆涓嶈鏀寔: {}", e.getMessage());
+                }
+            }
+
+            writer.setOutput(new MemoryCacheImageOutputStream(output));
+            writer.write(null, new IIOImage(image, null, null), param);
+
+        } finally {
+            writer.dispose();
         }
-
-        writer.setOutput(new MemoryCacheImageOutputStream(output));
-        writer.write(null, new IIOImage(image, null, null), param);
-        writer.dispose();
     }
 
 
@@ -259,7 +393,7 @@
      * 澶勭悊瑙嗛鏂囦欢锛氱敓鎴怋ase64缂栫爜鐨勫皝闈� (浣跨敤JavaCV)
      */
     public Map<String, Object> processVideo(File file, int width, int height,
-                                            float quality, String format, boolean deleteY) {
+                                            float quality, String format) {
         Map<String, Object> result = new HashMap<>();
 
         try {
@@ -300,15 +434,6 @@
             log.error("瑙嗛灏侀潰鐢熸垚澶辫触", e);
             result.put("success", false);
             result.put("message", "灏侀潰鐢熸垚澶辫触: " + e.getMessage());
-        } finally {
-            // 娓呯悊涓存椂鏂囦欢
-            if (deleteY && file != null && file.exists()) {
-                try {
-                    file.delete();
-                } catch (Exception e) {
-                    log.warn("鍒犻櫎涓存椂瑙嗛鏂囦欢鏃跺嚭閿�", e);
-                }
-            }
         }
         return result;
     }

--
Gitblit v1.9.1