修改模糊图

dev
zhaokai 2026-03-11 17:13:21 +08:00
parent 473998f9ce
commit 6dcafcca0a
1 changed files with 70 additions and 24 deletions

View File

@ -2,6 +2,9 @@ package com.zcloud.edu.domain.utils;
import com.deepoove.poi.data.PictureRenderData; import com.deepoove.poi.data.PictureRenderData;
import com.deepoove.poi.data.Pictures; import com.deepoove.poi.data.Pictures;
import com.drew.imaging.ImageMetadataReader;
import com.drew.metadata.Metadata;
import com.drew.metadata.exif.ExifIFD0Directory;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.imageio.ImageReader; import javax.imageio.ImageReader;
@ -27,12 +30,19 @@ public class FixedPictureUtils {
* @return PictureRenderData * @return PictureRenderData
* @throws IOException IO * @throws IOException IO
*/ */
public static PictureRenderData ofNormalUrl(String imgUrl, int width, int height) throws IOException { public static PictureRenderData ofNormalUrl(String imgUrl, int width, int height) {
try{
byte[] imgBytes = readBytesFromUrl(imgUrl); byte[] imgBytes = readBytesFromUrl(imgUrl);
byte[] fixedImgBytes = fixImageRotation(imgBytes); byte[] fixedImgBytes = fixImageRotation(imgBytes);
return Pictures.ofBytes(fixedImgBytes) return Pictures.ofBytes(fixedImgBytes)
.size(width, height) .size(width, height)
.create(); .create();
}catch (Exception e){
return Pictures.ofUrl(imgUrl)
.size(width, height)
.create();
}
} }
/** /**
@ -54,31 +64,67 @@ public class FixedPictureUtils {
/** /**
* JDK 8 * JDK 8
*/ */
private static byte[] fixImageRotation(byte[] imageBytes) throws IOException { private static byte[] fixImageRotation(byte[] imageBytes) throws Exception {
// 1. 解析EXIF旋转角度 try (ByteArrayInputStream bais = new ByteArrayInputStream(imageBytes)) {
int rotation = getExifRotation(imageBytes); // 1. 读取 EXIF 元数据
Metadata metadata = ImageMetadataReader.readMetadata(bais);
// 2. 兜底检测无EXIF时自动判断 // 2. 获取旋转角度
if (rotation == 0) { int rotation = getRotationFromMetadata(metadata);
rotation = detectImageOrientation(imageBytes);
}
// 3. 无需旋转则返回原字节 // 3. 如果不需要旋转,直接返回原字节
if (rotation == 0) { if (rotation == 0) {
return imageBytes; return imageBytes;
} }
// 4. 读取并旋转图片 // 4. 读取并旋转图片
BufferedImage original = readImage(imageBytes); bais.reset(); // 重置流到开始位置
BufferedImage original = ImageIO.read(bais);
BufferedImage rotated = rotateImage(original, rotation); BufferedImage rotated = rotateImage(original, rotation);
// 5. 转为字节返回 // 5. 转为字节数组返回
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
String format = getImageFormat(imageBytes); String format = getImageFormat(imageBytes);
ImageIO.write(rotated, format, baos); ImageIO.write(rotated, format, baos);
return baos.toByteArray(); return baos.toByteArray();
} }
} }
}
/**
* EXIF
* 0-90/180/270-
*/
/**
* Metadata
* @param metadata EXIF
* @return 0/90/180/270
*/
private static int getRotationFromMetadata(Metadata metadata) {
try {
ExifIFD0Directory exifIFD0Directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
if (exifIFD0Directory == null || !exifIFD0Directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) {
return 0; // 没有 EXIF 或 Orientation 标签,不需要旋转
}
int orientation = exifIFD0Directory.getInt(ExifIFD0Directory.TAG_ORIENTATION);
// 根据 Orientation 值返回对应的旋转角度
switch (orientation) {
case 3: // 旋转 180 度
return 180;
case 6: // 顺时针旋转 90 度
return 90;
case 8: // 逆时针旋转 90 度270 度)
return 270;
default: // 1 或其他,不需要旋转
return 0;
}
} catch (Exception e) {
// 任何异常都返回 0 度
return 0;
}
}
/** /**
* JDK 8EXIFswitch * JDK 8EXIFswitch