This commit is contained in:
2025-11-28 15:59:44 +08:00
parent 27ed834c09
commit 775a7a3cc2
2 changed files with 149 additions and 25 deletions

View File

@@ -5,6 +5,7 @@ import com.itextpdf.text.pdf.PdfDocument;
import com.itextpdf.text.pdf.PdfReader;
import com.point.strategy.archiveFile.service.ArchiveFileService;
import com.point.strategy.common.*;
import com.point.strategy.common.ImageToPdfConverter;
import com.point.strategy.user.bean.User;
import com.point.strategy.user.service.UserService;
import io.swagger.annotations.Api;
@@ -170,36 +171,37 @@ public class ArchiveFileController {
}else {
// 大文件直接返回,不加水印
if (isLargeFile) {
String contentType = "image/jpeg";
if (split[split.length-1].equalsIgnoreCase("png")) {
contentType = "image/png";
}
response.setContentType(contentType + ";charset=UTF-8");
try (InputStream in = new FileInputStream(file);
ServletOutputStream out = response.getOutputStream()) {
// 将图片转换为PDF
try (InputStream in = new FileInputStream(file)) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageToPdfConverter.convertImageToPdf(in, outputStream);
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
response.setContentType("application/pdf;charset=UTF-8");
try (ServletOutputStream out = response.getOutputStream()) {
out.write(outputStream.toByteArray());
out.flush();
}
out.flush();
} catch (Exception e) {
log.error("图片转PDF失败: {}", e.getMessage(), e);
throw new IOException("图片转PDF失败: " + e.getMessage(), e);
}
} else {
// 小文件加水印处理
ByteArrayOutputStream outputStream = addWatermarkByFileIo(downLoadPath, user.getUsername());
// 根据文件类型设置正确的Content-Type
String contentType = "image/jpeg";
if (split[split.length-1].equalsIgnoreCase("png")) {
contentType = "image/png";
}
response.setContentType(contentType + ";charset=UTF-8");
try (ServletOutputStream out = response.getOutputStream()) {
out.write(outputStream.toByteArray());
out.flush();
// 小文件加水印处理然后转换为PDF
ByteArrayOutputStream imageStream = addWatermarkByFileIo(downLoadPath, user.getUsername());
try (InputStream in = new ByteArrayInputStream(imageStream.toByteArray())) {
ByteArrayOutputStream pdfStream = new ByteArrayOutputStream();
ImageToPdfConverter.convertImageToPdf(in, pdfStream);
response.setContentType("application/pdf;charset=UTF-8");
try (ServletOutputStream out = response.getOutputStream()) {
out.write(pdfStream.toByteArray());
out.flush();
}
} catch (Exception e) {
log.error("图片转PDF失败: {}", e.getMessage(), e);
throw new IOException("图片转PDF失败: " + e.getMessage(), e);
} finally {
outputStream.close();
imageStream.close();
}
}
}

View File

@@ -0,0 +1,122 @@
package com.point.strategy.common;
import com.drew.imaging.ImageMetadataReader;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.exif.ExifDirectoryBase;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfWriter;
import lombok.extern.slf4j.Slf4j;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* 图片转PDF工具类
* 支持将jpg、png等图片格式转换为PDF
*/
@Slf4j
public class ImageToPdfConverter {
/**
* 将图片输入流转换为PDF输出流
*
* @param imageInputStream 图片输入流
* @param pdfOutputStream PDF输出流
* @throws IOException IO异常
* @throws DocumentException 文档异常
*/
public static void convertImageToPdf(InputStream imageInputStream, ByteArrayOutputStream pdfOutputStream)
throws IOException, DocumentException {
try {
// 创建临时文件来获取EXIF信息因为ImageMetadataReader需要File对象
// 由于我们只有InputStream需要先创建临时图片文件
java.io.File tempImageFile = java.io.File.createTempFile("temp_image_", ".jpg");
tempImageFile.deleteOnExit();
// 将输入流写入临时文件
try (java.io.FileOutputStream fos = new java.io.FileOutputStream(tempImageFile)) {
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = imageInputStream.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
}
// 读取图片并获取EXIF方向信息
Image image = Image.getInstance(tempImageFile.getAbsolutePath());
int orientation = getExifOrientation(tempImageFile);
// 根据EXIF方向调整图片
adjustImageOrientation(image, orientation);
// 创建PDF文档使用图片的原始尺寸
Document document = new Document(new Rectangle(image.getWidth(), image.getHeight()));
PdfWriter.getInstance(document, pdfOutputStream);
document.open();
// 添加图片到PDF
document.add(image);
document.close();
// 删除临时文件
tempImageFile.delete();
} catch (Exception e) {
log.error("图片转PDF失败: {}", e.getMessage(), e);
throw e;
}
}
/**
* 获取图片的EXIF方向信息
*
* @param imageFile 图片文件
* @return 方向值 (1=正常, 3=180度, 6=90度, 8=270度)
*/
private static int getExifOrientation(java.io.File imageFile) {
try {
Metadata metadata = ImageMetadataReader.readMetadata(imageFile);
// 遍历元数据目录,查找 EXIF 方向标签
for (Directory directory : metadata.getDirectories()) {
if (directory.containsTag(ExifDirectoryBase.TAG_ORIENTATION)) {
return directory.getInt(ExifDirectoryBase.TAG_ORIENTATION);
}
}
} catch (Exception e) {
log.warn("读取EXIF方向失败: {}", e.getMessage());
}
return 1; // 默认方向:正常
}
/**
* 根据EXIF方向调整图片
*
* @param image 图片对象
* @param orientation 方向值
* @throws DocumentException 文档异常
*/
private static void adjustImageOrientation(Image image, int orientation) throws DocumentException {
switch (orientation) {
case 1: // 正常
break;
case 3: // 旋转180度
image.setRotationDegrees(180);
break;
case 6: // 顺时针旋转90度
image.setRotationDegrees(90);
break;
case 8: // 逆时针旋转90度
image.setRotationDegrees(270);
break;
default:
// 其他情况保持原样
break;
}
}
}