| | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | |
| | | |
| | | |
| | | /** |
| | | * 读取图片并处理EXIF方向 |
| | | */ |
| | | 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: // 正常 |
| | | 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) 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", "无法读取图片文件"); |