修复导出一人一档人脸
parent
dcab2e37cf
commit
31e179d5f6
|
|
@ -4,8 +4,6 @@ import cn.hutool.core.bean.BeanUtil;
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
import com.alibaba.cola.dto.PageResponse;
|
import com.alibaba.cola.dto.PageResponse;
|
||||||
import com.alibaba.cola.exception.BizException;
|
|
||||||
import com.alibaba.cola.statemachine.impl.SysOutVisitor;
|
|
||||||
import com.deepoove.poi.data.PictureRenderData;
|
import com.deepoove.poi.data.PictureRenderData;
|
||||||
import com.deepoove.poi.data.PictureType;
|
import com.deepoove.poi.data.PictureType;
|
||||||
import com.deepoove.poi.data.Pictures;
|
import com.deepoove.poi.data.Pictures;
|
||||||
|
|
@ -22,7 +20,6 @@ import com.zcloud.edu.domain.model.archives.ArchivesPdfFileE;
|
||||||
import com.zcloud.edu.domain.model.archives.ClassArchivesE;
|
import com.zcloud.edu.domain.model.archives.ClassArchivesE;
|
||||||
import com.zcloud.edu.domain.model.archives.PersonArchivesE;
|
import com.zcloud.edu.domain.model.archives.PersonArchivesE;
|
||||||
import com.zcloud.edu.domain.model.study.*;
|
import com.zcloud.edu.domain.model.study.*;
|
||||||
import com.zcloud.edu.domain.utils.FixedPictureUtils;
|
|
||||||
import com.zcloud.edu.domain.utils.ImageUtil;
|
import com.zcloud.edu.domain.utils.ImageUtil;
|
||||||
import com.zcloud.edu.dto.archives.ArchivesPdfFilePageQry;
|
import com.zcloud.edu.dto.archives.ArchivesPdfFilePageQry;
|
||||||
import com.zcloud.edu.dto.archives.ArchivesQry;
|
import com.zcloud.edu.dto.archives.ArchivesQry;
|
||||||
|
|
@ -47,21 +44,16 @@ import com.zcloud.gbscommon.utils.*;
|
||||||
import com.zcloud.gbscommon.zcloudimgfiles.facade.ZcloudImgFilesFacade;
|
import com.zcloud.gbscommon.zcloudimgfiles.facade.ZcloudImgFilesFacade;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.coobird.thumbnailator.Thumbnails;
|
|
||||||
import org.apache.commons.beanutils.PropertyUtils;
|
import org.apache.commons.beanutils.PropertyUtils;
|
||||||
import org.apache.commons.io.output.ByteArrayOutputStream;
|
import org.apache.commons.io.output.ByteArrayOutputStream;
|
||||||
import org.apache.dubbo.config.annotation.DubboReference;
|
import org.apache.dubbo.config.annotation.DubboReference;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.scheduling.annotation.Async;
|
import org.springframework.scheduling.annotation.Async;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
@ -427,7 +419,8 @@ public class ArchivesQueryExe {
|
||||||
public byte[] execteStudentRecord(PersonArchivesDTO params){
|
public byte[] execteStudentRecord(PersonArchivesDTO params){
|
||||||
try {
|
try {
|
||||||
Map<String, Object> workItem = PropertyUtils.describe( params);
|
Map<String, Object> workItem = PropertyUtils.describe( params);
|
||||||
PictureRenderData picture = Pictures.ofUrl(fileUrlConfig.getPrefixUrl() + params.getUserAvatarUrl(), PictureType.JPEG).size(100, 100).create();//网络图片地址
|
// PictureRenderData picture = Pictures.ofUrl(fileUrlConfig.getPrefixUrl() + params.getUserAvatarUrl(), PictureType.JPEG).size(100, 100).create();//网络图片地址
|
||||||
|
PictureRenderData picture = ImageUtil.createWithThumbnailator(fileUrlConfig.getPrefixUrl() + params.getUserAvatarUrl(), 100, 100);
|
||||||
workItem.put("img", picture);
|
workItem.put("img", picture);
|
||||||
String templatePath = "templates/template/studentInfo.docx";
|
String templatePath = "templates/template/studentInfo.docx";
|
||||||
ByteArrayOutputStream outputStream = Tools.renderTemplate(templatePath, workItem);
|
ByteArrayOutputStream outputStream = Tools.renderTemplate(templatePath, workItem);
|
||||||
|
|
@ -444,11 +437,13 @@ public class ArchivesQueryExe {
|
||||||
try {
|
try {
|
||||||
Map<String, Object> workItem = PropertyUtils.describe( params);
|
Map<String, Object> workItem = PropertyUtils.describe( params);
|
||||||
if(!ObjectUtils.isEmpty(params.getSignFaceUrl())){
|
if(!ObjectUtils.isEmpty(params.getSignFaceUrl())){
|
||||||
PictureRenderData signFacePicture = Pictures.ofUrl(fileUrlConfig.getPrefixUrl() + params.getSignFaceUrl(), PictureType.JPEG).size(100, 100).create();//网络图片地址
|
// PictureRenderData signFacePicture = Pictures.ofUrl(fileUrlConfig.getPrefixUrl() + params.getSignFaceUrl(), PictureType.JPEG).size(100, 100).create();//网络图片地址
|
||||||
|
PictureRenderData signFacePicture = ImageUtil.createWithThumbnailator(fileUrlConfig.getPrefixUrl() + params.getSignFaceUrl(), 100, 100);
|
||||||
workItem.put("signFacePicture", signFacePicture);
|
workItem.put("signFacePicture", signFacePicture);
|
||||||
}
|
}
|
||||||
if (!ObjectUtils.isEmpty(params.getExamSignFaceUrl())) {
|
if (!ObjectUtils.isEmpty(params.getExamSignFaceUrl())) {
|
||||||
PictureRenderData examSignFacePicture = Pictures.ofUrl(fileUrlConfig.getPrefixUrl() + params.getExamSignFaceUrl(), PictureType.JPEG).size(100, 100).create();//网络图片地址
|
// PictureRenderData examSignFacePicture = Pictures.ofUrl(fileUrlConfig.getPrefixUrl() + params.getExamSignFaceUrl(), PictureType.JPEG).size(100, 100).create();//网络图片地址
|
||||||
|
PictureRenderData examSignFacePicture = ImageUtil.createWithThumbnailator(fileUrlConfig.getPrefixUrl() + params.getExamSignFaceUrl(), 100, 100);
|
||||||
workItem.put("examSignFacePicture", examSignFacePicture);
|
workItem.put("examSignFacePicture", examSignFacePicture);
|
||||||
// String imageUrl = fileUrlConfig.getPrefixUrl() + params.getExamSignFaceUrl();
|
// String imageUrl = fileUrlConfig.getPrefixUrl() + params.getExamSignFaceUrl();
|
||||||
// try (InputStream is = new URL(imageUrl).openStream()) {
|
// try (InputStream is = new URL(imageUrl).openStream()) {
|
||||||
|
|
@ -522,7 +517,8 @@ public class ArchivesQueryExe {
|
||||||
workItem.put("name", params.getName());
|
workItem.put("name", params.getName());
|
||||||
workItem.put("className", params.getClassName());
|
workItem.put("className", params.getClassName());
|
||||||
if(!ObjectUtils.isEmpty(params.getStudentExamRecord().getSignUrl())){
|
if(!ObjectUtils.isEmpty(params.getStudentExamRecord().getSignUrl())){
|
||||||
PictureRenderData signPicture = Pictures.ofUrl(fileUrlConfig.getPrefixUrl() + params.getStudentExamRecord().getSignUrl(), PictureType.JPEG).size(50, 15).create();//网络图片地址
|
// PictureRenderData signPicture = Pictures.ofUrl(fileUrlConfig.getPrefixUrl() + params.getStudentExamRecord().getSignUrl(), PictureType.JPEG).size(50, 15).create();//网络图片地址
|
||||||
|
PictureRenderData signPicture = ImageUtil.createWithThumbnailator(fileUrlConfig.getPrefixUrl() + params.getStudentExamRecord(), 50, 15);
|
||||||
workItem.put("signPicture", signPicture);
|
workItem.put("signPicture", signPicture);
|
||||||
}
|
}
|
||||||
String templatePath = "templates/template/exam.docx";
|
String templatePath = "templates/template/exam.docx";
|
||||||
|
|
@ -879,7 +875,9 @@ public class ArchivesQueryExe {
|
||||||
AtomicInteger atomicIndex = new AtomicInteger(1);
|
AtomicInteger atomicIndex = new AtomicInteger(1);
|
||||||
for (StudentSignCO item : params.getSignList()){
|
for (StudentSignCO item : params.getSignList()){
|
||||||
Map<String, Object> itemMap = PropertyUtils.describe(item);
|
Map<String, Object> itemMap = PropertyUtils.describe(item);
|
||||||
PictureRenderData picture = Pictures.ofUrl(fileUrlConfig.getPrefixUrl() + item.getSignUrl(), PictureType.JPEG).size(100, 100).create();//网络图片地址
|
// PictureRenderData picture = Pictures.ofUrl(fileUrlConfig.getPrefixUrl() + item.getSignUrl(), PictureType.JPEG).size(100, 100).create();//网络图片地址
|
||||||
|
PictureRenderData picture = ImageUtil.createWithThumbnailator(fileUrlConfig.getPrefixUrl() + item.getSignUrl(), 100, 100);
|
||||||
|
|
||||||
itemMap.put("picture", picture);
|
itemMap.put("picture", picture);
|
||||||
int index = atomicIndex.getAndIncrement();
|
int index = atomicIndex.getAndIncrement();
|
||||||
itemMap.put("index", index);
|
itemMap.put("index", index);
|
||||||
|
|
@ -913,21 +911,17 @@ public class ArchivesQueryExe {
|
||||||
Map<String, Object> itemMap = PropertyUtils.describe(item);
|
Map<String, Object> itemMap = PropertyUtils.describe(item);
|
||||||
if(!ObjectUtils.isEmpty(item.getSignFaceUrl())){
|
if(!ObjectUtils.isEmpty(item.getSignFaceUrl())){
|
||||||
// PictureRenderData signPicture = Pictures.ofUrl(fileUrlConfig.getPrefixUrl() + item.getSignFaceUrl(), PictureType.JPEG).size(50, 50).create();//网络图片地址
|
// PictureRenderData signPicture = Pictures.ofUrl(fileUrlConfig.getPrefixUrl() + item.getSignFaceUrl(), PictureType.JPEG).size(50, 50).create();//网络图片地址
|
||||||
// PictureRenderData signPicture = FixedPictureUtils.ofNormalUrl(fileUrlConfig.getPrefixUrl() + item.getSignFaceUrl(), 50, 50);
|
|
||||||
PictureRenderData signPicture = ImageUtil.createWithThumbnailator(fileUrlConfig.getPrefixUrl() + item.getSignFaceUrl(), 50, 50);
|
PictureRenderData signPicture = ImageUtil.createWithThumbnailator(fileUrlConfig.getPrefixUrl() + item.getSignFaceUrl(), 50, 50);
|
||||||
|
|
||||||
itemMap.put("signPicture", signPicture);
|
itemMap.put("signPicture", signPicture);
|
||||||
}
|
}
|
||||||
if(!ObjectUtils.isEmpty(item.getExamFaceUrl())){
|
if(!ObjectUtils.isEmpty(item.getExamFaceUrl())){
|
||||||
// PictureRenderData examPicture = Pictures.ofUrl(fileUrlConfig.getPrefixUrl() + item.getExamFaceUrl(), PictureType.JPEG).size(50, 50).create();//网络图片地址
|
// PictureRenderData examPicture = Pictures.ofUrl(fileUrlConfig.getPrefixUrl() + item.getExamFaceUrl(), PictureType.JPEG).size(50, 50).create();//网络图片地址
|
||||||
// PictureRenderData examPicture = FixedPictureUtils.ofNormalUrl(fileUrlConfig.getPrefixUrl() + item.getExamFaceUrl(), 50, 50);
|
|
||||||
PictureRenderData examPicture = ImageUtil.createWithThumbnailator(fileUrlConfig.getPrefixUrl() + item.getExamFaceUrl(), 50, 50);
|
PictureRenderData examPicture = ImageUtil.createWithThumbnailator(fileUrlConfig.getPrefixUrl() + item.getExamFaceUrl(), 50, 50);
|
||||||
|
|
||||||
itemMap.put("examPicture", examPicture);
|
itemMap.put("examPicture", examPicture);
|
||||||
}
|
}
|
||||||
if(!ObjectUtils.isEmpty(item.getUserAvatarUrl())){
|
if(!ObjectUtils.isEmpty(item.getUserAvatarUrl())){
|
||||||
// PictureRenderData facePicture = Pictures.ofUrl(fileUrlConfig.getPrefixUrl() + item.getUserAvatarUrl(), PictureType.JPEG).size(50, 50).style("rotation:90;").create();//网络图片地址
|
// PictureRenderData facePicture = Pictures.ofUrl(fileUrlConfig.getPrefixUrl() + item.getUserAvatarUrl(), PictureType.JPEG).size(50, 50).style("rotation:90;").create();//网络图片地址
|
||||||
// PictureRenderData facePicture = FixedPictureUtils.ofNormalUrl(fileUrlConfig.getPrefixUrl() + item.getUserAvatarUrl(), 50, 50);
|
|
||||||
PictureRenderData facePicture = ImageUtil.createWithThumbnailator(fileUrlConfig.getPrefixUrl() + item.getUserAvatarUrl(), 50, 50);
|
PictureRenderData facePicture = ImageUtil.createWithThumbnailator(fileUrlConfig.getPrefixUrl() + item.getUserAvatarUrl(), 50, 50);
|
||||||
|
|
||||||
itemMap.put("facePicture", facePicture);
|
itemMap.put("facePicture", facePicture);
|
||||||
|
|
|
||||||
|
|
@ -1,199 +0,0 @@
|
||||||
package com.zcloud.edu.domain.utils;
|
|
||||||
|
|
||||||
import com.deepoove.poi.data.PictureRenderData;
|
|
||||||
import com.deepoove.poi.data.Pictures;
|
|
||||||
|
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import javax.imageio.ImageReader;
|
|
||||||
import javax.imageio.metadata.IIOMetadata;
|
|
||||||
import javax.imageio.metadata.IIOMetadataNode;
|
|
||||||
import javax.imageio.stream.ImageInputStream;
|
|
||||||
|
|
||||||
public class FixedPictureUtils {
|
|
||||||
/**
|
|
||||||
* 替代Pictures.ofUrl(),返回正常方向的PictureRenderData
|
|
||||||
* @param imgUrl 图片URL
|
|
||||||
* @param width 插入宽度(px)
|
|
||||||
* @param height 插入高度(px)
|
|
||||||
* @return 正常显示的PictureRenderData
|
|
||||||
* @throws IOException IO异常
|
|
||||||
*/
|
|
||||||
public static PictureRenderData ofNormalUrl(String imgUrl, int width, int height) throws IOException {
|
|
||||||
// 1. 从URL读取图片字节(纯JDK8原生)
|
|
||||||
byte[] imgBytes = readBytesFromUrl(imgUrl);
|
|
||||||
// 2. 修复图片旋转(核心:移除containsTree()依赖)
|
|
||||||
byte[] fixedImgBytes = fixImageRotationForJdk8(imgBytes);
|
|
||||||
// 3. 构建PictureRenderData(使用ofBytes方法)
|
|
||||||
return Pictures.ofBytes(fixedImgBytes)
|
|
||||||
.size(width, height)
|
|
||||||
.create();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JDK8原生:从URL读取字节数组(无第三方依赖)
|
|
||||||
*/
|
|
||||||
private static byte[] readBytesFromUrl(String url) throws IOException {
|
|
||||||
URL picUrl = new URL(url);
|
|
||||||
try (InputStream is = picUrl.openStream();
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
int len;
|
|
||||||
while ((len = is.read(buffer)) != -1) {
|
|
||||||
baos.write(buffer, 0, len);
|
|
||||||
}
|
|
||||||
return baos.toByteArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 核心:修复图片EXIF旋转(移除containsTree()依赖)
|
|
||||||
*/
|
|
||||||
private static byte[] fixImageRotationForJdk8(byte[] imageBytes) throws IOException {
|
|
||||||
try (ByteArrayInputStream bais = new ByteArrayInputStream(imageBytes);
|
|
||||||
ImageInputStream iis = ImageIO.createImageInputStream(bais)) {
|
|
||||||
|
|
||||||
// 获取图片读取器
|
|
||||||
Iterator<ImageReader> readers = ImageIO.getImageReaders(iis);
|
|
||||||
if (!readers.hasNext()) {
|
|
||||||
return imageBytes; // 无读取器,返回原字节
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageReader reader = readers.next();
|
|
||||||
reader.setInput(iis, true);
|
|
||||||
|
|
||||||
// 1. 获取旋转角度(绕开containsTree())
|
|
||||||
int rotation = getExifRotationWithoutContainsTree(reader);
|
|
||||||
if (rotation == 0) {
|
|
||||||
reader.dispose();
|
|
||||||
return imageBytes; // 无需旋转,直接返回
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 读取原始图片
|
|
||||||
BufferedImage original = reader.read(0);
|
|
||||||
reader.dispose();
|
|
||||||
|
|
||||||
// 3. 旋转图片
|
|
||||||
BufferedImage rotated = rotateImageForJdk8(original, rotation);
|
|
||||||
|
|
||||||
// 4. 转为字节返回
|
|
||||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
|
||||||
String format = getImageFormatForJdk8(imageBytes);
|
|
||||||
ImageIO.write(rotated, format, baos);
|
|
||||||
return baos.toByteArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 关键修正:绕开containsTree(),解析EXIF旋转角度
|
|
||||||
*/
|
|
||||||
private static int getExifRotationWithoutContainsTree(ImageReader reader) {
|
|
||||||
try {
|
|
||||||
IIOMetadata metadata = reader.getImageMetadata(0);
|
|
||||||
String exifFormat = "javax_imageio_jpeg_image_1.0";
|
|
||||||
|
|
||||||
// 直接尝试获取元数据树,不先判断containsTree()
|
|
||||||
// 捕获异常即可,无需提前检查
|
|
||||||
Object metadataTree;
|
|
||||||
try {
|
|
||||||
metadataTree = metadata.getAsTree(exifFormat);
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
// 不支持该格式,返回0度
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(metadataTree instanceof IIOMetadataNode)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
IIOMetadataNode root = (IIOMetadataNode) metadataTree;
|
|
||||||
IIOMetadataNode exifNode = getChildNodeForJdk8(root, "app0JFIF");
|
|
||||||
if (exifNode == null) {
|
|
||||||
exifNode = getChildNodeForJdk8(root, "exif");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (exifNode == null) return 0;
|
|
||||||
|
|
||||||
// 解析Orientation参数
|
|
||||||
String orientation = exifNode.getAttribute("Orientation");
|
|
||||||
if (orientation == null || orientation.trim().isEmpty()) return 0;
|
|
||||||
|
|
||||||
int ori = Integer.parseInt(orientation);
|
|
||||||
switch (ori) {
|
|
||||||
case 3: return 180;
|
|
||||||
case 6: return 90;
|
|
||||||
case 8: return 270;
|
|
||||||
default: return 0;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
// 任何异常都返回0度(比如元数据解析失败)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JDK8适配:获取XML子节点
|
|
||||||
*/
|
|
||||||
private static IIOMetadataNode getChildNodeForJdk8(IIOMetadataNode parent, String name) {
|
|
||||||
for (int i = 0; i < parent.getLength(); i++) {
|
|
||||||
Object item = parent.item(i);
|
|
||||||
if (item instanceof IIOMetadataNode) {
|
|
||||||
IIOMetadataNode node = (IIOMetadataNode) item;
|
|
||||||
if (name.equals(node.getNodeName())) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JDK8适配:旋转图片(解决JDK8 Graphics2D兼容问题)
|
|
||||||
*/
|
|
||||||
private static BufferedImage rotateImageForJdk8(BufferedImage img, int angle) {
|
|
||||||
int width = img.getWidth();
|
|
||||||
int height = img.getHeight();
|
|
||||||
|
|
||||||
// 计算旋转后的画布尺寸
|
|
||||||
int newWidth = (angle % 180 == 0) ? width : height;
|
|
||||||
int newHeight = (angle % 180 == 0) ? height : width;
|
|
||||||
|
|
||||||
// JDK8兼容:创建BufferedImage(避免透明通道问题)
|
|
||||||
BufferedImage rotated = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
|
|
||||||
Graphics2D g2d = rotated.createGraphics();
|
|
||||||
|
|
||||||
// 抗锯齿,避免旋转后模糊(JDK8必须)
|
|
||||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
|
||||||
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
|
||||||
|
|
||||||
// 旋转图片
|
|
||||||
g2d.rotate(Math.toRadians(angle), newWidth / 2.0, newHeight / 2.0);
|
|
||||||
g2d.drawImage(img, (newWidth - width) / 2, (newHeight - height) / 2, null);
|
|
||||||
g2d.dispose();
|
|
||||||
|
|
||||||
return rotated;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JDK8适配:识别图片格式(jpg/png)
|
|
||||||
*/
|
|
||||||
private static String getImageFormatForJdk8(byte[] imageBytes) {
|
|
||||||
if (imageBytes.length < 4) return "jpg";
|
|
||||||
// JDK8字节判断,兼容所有系统
|
|
||||||
if (imageBytes[0] == (byte)0xFF && imageBytes[1] == (byte)0xD8) {
|
|
||||||
return "jpg";
|
|
||||||
} else if (imageBytes[0] == (byte)0x89 && imageBytes[1] == (byte)0x50) {
|
|
||||||
return "png";
|
|
||||||
}
|
|
||||||
return "jpg";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -21,7 +21,7 @@ public class ImageUtil {
|
||||||
// 使用Thumbnailator处理 - 一行代码搞定旋转和缩放
|
// 使用Thumbnailator处理 - 一行代码搞定旋转和缩放
|
||||||
BufferedImage processed = Thumbnails.of(original)
|
BufferedImage processed = Thumbnails.of(original)
|
||||||
.size(width, height)
|
.size(width, height)
|
||||||
.rotate(180) // 如果需要固定旋转,可以直接指定
|
.rotate(90) // 如果需要固定旋转,可以直接指定
|
||||||
.asBufferedImage();
|
.asBufferedImage();
|
||||||
|
|
||||||
// 或者使用EXIF自动旋转(如果Thumbnailator版本支持)
|
// 或者使用EXIF自动旋转(如果Thumbnailator版本支持)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue