修改模糊图

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.Pictures;
import com.drew.imaging.ImageMetadataReader;
import com.drew.metadata.Metadata;
import com.drew.metadata.exif.ExifIFD0Directory;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
@ -27,12 +30,19 @@ public class FixedPictureUtils {
* @return PictureRenderData
* @throws IOException IO
*/
public static PictureRenderData ofNormalUrl(String imgUrl, int width, int height) throws IOException {
byte[] imgBytes = readBytesFromUrl(imgUrl);
byte[] fixedImgBytes = fixImageRotation(imgBytes);
return Pictures.ofBytes(fixedImgBytes)
.size(width, height)
.create();
public static PictureRenderData ofNormalUrl(String imgUrl, int width, int height) {
try{
byte[] imgBytes = readBytesFromUrl(imgUrl);
byte[] fixedImgBytes = fixImageRotation(imgBytes);
return Pictures.ofBytes(fixedImgBytes)
.size(width, height)
.create();
}catch (Exception e){
return Pictures.ofUrl(imgUrl)
.size(width, height)
.create();
}
}
/**
@ -54,29 +64,65 @@ public class FixedPictureUtils {
/**
* JDK 8
*/
private static byte[] fixImageRotation(byte[] imageBytes) throws IOException {
// 1. 解析EXIF旋转角度
int rotation = getExifRotation(imageBytes);
private static byte[] fixImageRotation(byte[] imageBytes) throws Exception {
try (ByteArrayInputStream bais = new ByteArrayInputStream(imageBytes)) {
// 1. 读取 EXIF 元数据
Metadata metadata = ImageMetadataReader.readMetadata(bais);
// 2. 兜底检测无EXIF时自动判断
if (rotation == 0) {
rotation = detectImageOrientation(imageBytes);
// 2. 获取旋转角度
int rotation = getRotationFromMetadata(metadata);
// 3. 如果不需要旋转,直接返回原字节
if (rotation == 0) {
return imageBytes;
}
// 4. 读取并旋转图片
bais.reset(); // 重置流到开始位置
BufferedImage original = ImageIO.read(bais);
BufferedImage rotated = rotateImage(original, rotation);
// 5. 转为字节数组返回
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
String format = getImageFormat(imageBytes);
ImageIO.write(rotated, format, baos);
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);
// 3. 无需旋转则返回原字节
if (rotation == 0) {
return imageBytes;
}
if (exifIFD0Directory == null || !exifIFD0Directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) {
return 0; // 没有 EXIF 或 Orientation 标签,不需要旋转
}
// 4. 读取并旋转图片
BufferedImage original = readImage(imageBytes);
BufferedImage rotated = rotateImage(original, rotation);
int orientation = exifIFD0Directory.getInt(ExifIFD0Directory.TAG_ORIENTATION);
// 5. 转为字节返回
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
String format = getImageFormat(imageBytes);
ImageIO.write(rotated, format, baos);
return baos.toByteArray();
// 根据 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;
}
}