修复导出一人一档人脸

dev
zhaokai 2026-03-11 10:57:22 +08:00
parent 04dcced854
commit bef972ca0d
3 changed files with 61 additions and 11 deletions

View File

@ -64,6 +64,12 @@
<artifactId>thumbnailator</artifactId> <artifactId>thumbnailator</artifactId>
<version>0.4.20</version> <version>0.4.20</version>
</dependency> </dependency>
<dependency>
<groupId>com.drewnoakes</groupId>
<artifactId>metadata-extractor</artifactId>
<version>2.19.0</version>
</dependency>
<dependency> <dependency>
<groupId>com.jjb.saas</groupId> <groupId>com.jjb.saas</groupId>
<artifactId>jjb-saas-system-client</artifactId> <artifactId>jjb-saas-system-client</artifactId>

View File

@ -22,5 +22,9 @@
<groupId>com.jjb.saas</groupId> <groupId>com.jjb.saas</groupId>
<artifactId>jjb-saas-base-starter</artifactId> <artifactId>jjb-saas-base-starter</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.drewnoakes</groupId>
<artifactId>metadata-extractor</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -9,26 +9,37 @@ import javax.imageio.ImageIO;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.net.URL; import java.net.URL;
import net.coobird.thumbnailator.Thumbnails; import com.drew.imaging.ImageMetadataReader;
import net.coobird.thumbnailator.geometry.Positions; import com.drew.metadata.Metadata;
import com.drew.metadata.exif.ExifIFD0Directory;
public class ImageUtil { public class ImageUtil {
public static PictureRenderData createWithThumbnailator(String imageUrl, int width, int height) { public static PictureRenderData createWithThumbnailator(String imageUrl, int width, int height) {
try { try {
// 下载原图 // 下载原图
URL url = new URL(imageUrl); URL url = new URL(imageUrl);
BufferedImage original = ImageIO.read(url); BufferedImage originalImage = ImageIO.read(url);
// 使用Thumbnailator处理 - 一行代码搞定旋转和缩放 // 1. 读取EXIF判断是否需要旋转
BufferedImage processed = Thumbnails.of(original) int rotationAngle = getRotationAngleFromExif(url);
// 2. 根据判断结果决定是否旋转
BufferedImage processedImage;
if (rotationAngle != 0) {
// 需要旋转
processedImage = Thumbnails.of(originalImage)
.size(width, height) .size(width, height)
.rotate(270) // 如果需要固定旋转,可以直接指定 .rotate(rotationAngle)
.asBufferedImage(); .asBufferedImage();
} else {
// 不需要旋转,只缩放
processedImage = Thumbnails.of(originalImage)
.size(width, height)
.asBufferedImage();
}
// 或者使用EXIF自动旋转如果Thumbnailator版本支持 // 3. 转换为byte数组
// Thumbnails.of(original).scale(1.0).useExifOrientation().asBufferedImage();
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(processed, "jpg", baos); ImageIO.write(processedImage, "jpg", baos);
return Pictures.ofBytes(baos.toByteArray(), PictureType.JPEG) return Pictures.ofBytes(baos.toByteArray(), PictureType.JPEG)
.size(width, height) .size(width, height)
@ -40,4 +51,33 @@ public class ImageUtil {
.create(); .create();
} }
} }
/**
* EXIF
* 0-90/180/270-
*/
private static int getRotationAngleFromExif(URL url) {
try {
Metadata metadata = ImageMetadataReader.readMetadata(url.openStream());
ExifIFD0Directory exifDir = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
if (exifDir != null && exifDir.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) {
int orientation = exifDir.getInt(ExifIFD0Directory.TAG_ORIENTATION);
// 根据Orientation值返回需要的旋转角度 [citation:9]
switch (orientation) {
case 3: // 需要旋转180度
return 180;
case 6: // 需要顺时针旋转90度最常见手机竖拍
return 90;
case 8: // 需要逆时针旋转90度
return 270;
default: // 1或其他不需要旋转
return 0;
}
}
} catch (Exception e) {
// 忽略EXIF读取错误返回0表示不旋转
}
return 0;
}
} }