业务背景:用户在手机APP上进行签名,前端将签完名字的图片传入后端,后端合成新的pdf.
废话不多说,上代码:
//控制层代码
@PostMapping("/imageToPdf")
public Result imageToPdf(@RequestParam("linkName") String name, @RequestParam("file")
MultipartFile file) throws IOException {
try {
String format = LocalDateTimeUtil.format(LocalDateTime.now(),
DatePattern.PURE_DATETIME_MS_PATTERN);
File f = convertMultipartFileToFile(file);
//缩放图片
ImgUtil.scale(FileUtil.file(f), FileUtil.file("/hetong/dev/image/" + format +
".png"), 0.06f);
// 旋转270度
BufferedImage image = (BufferedImage)
//此处利用hutool工具类进行缩放
ImgUtil.rotate(ImageIO.read(FileUtil.file("/hetong/dev/image/" + format +
".png")), 270);
ImgUtil.write(image, FileUtil.file("/hetong/dev/image/" + format + "_result" +
".png"));
String imagePath = "/hetong/dev/image/" + format + "_result" + ".png";
String fileUrl = name; // 要下载的文件的HTTPS链接
String localFilePath = "/hetong/dev/" + format + ".pdf"; // 下载文件保存到本地的路径和名称
//String localFilePath = "D:\\soft\\ceshi\\" + format + ".pdf"; // 下载文件保存到本地的路径和名称
downloadFile(fileUrl, localFilePath);
String pdfPath = localFilePath;
String url = imageToPdfUtil.addImageToPDF(imagePath, pdfPath, format);
return new Result(ResultCode.SUCCESS, url);
} catch (IOException e) {
e.printStackTrace();
}
return new Result(ResultCode.IMAGE_MERGE_FAILED, "");
}
//工具类
@Component
public class ImageToPdfUtil {
private static Logger logger = LoggerFactory.getLogger(WordUtil.class);
@Autowired
private UploadManager uploadManager;
@Autowired
private Auth auth;
@Value("${qiniu.bucketName}")
private String bucketName;
@Value("${qiniu.path}")
private String url;
/**
* 添加图片至pdf指定位置
*
* @param imagePath
* @param pdfPath
* @throws IOException
*/
public String addImageToPDF(String imagePath, String pdfPath, String format) throws IOException {
// 加载图片
PDDocument document = PDDocument.load(new File(pdfPath));
PDPage lastPage = document.getPage(document.getNumberOfPages() - 1);
PDImageXObject image = PDImageXObject.createFromFile(imagePath, document);
// 获取图片宽度和高度
float imageWidth = image.getWidth();
float imageHeight = image.getHeight();
try (PDPageContentStream contentStream = new PDPageContentStream(document, lastPage, PDPageContentStream.AppendMode.APPEND, true, true)) {
// 设置图片位置
float x = (lastPage.getMediaBox().getWidth() / 2f - imageWidth / 2f) * 0.88f;
float y = (lastPage.getMediaBox().getHeight() / 2f - imageHeight / 2f) * 1.5f;
// 添加图片到指定位置
contentStream.drawImage(image, x, y, imageWidth, imageHeight);
}
// 保存修改后的 PDF
document.save(pdfPath);
document.close();
return uploadQiniu(format);
}
/**
* 上传到七牛云
*
* @param fileName
* @return
* @throws FileNotFoundException
* @throws QiniuException
*/
public String uploadQiniu(String fileName) throws FileNotFoundException, QiniuException {
//这里是上传到服务器路径下的,已经填充完数据的word
File file = ResourceUtils.getFile("/hetong/dev/" + fileName + ".pdf");
//File file = ResourceUtils.getFile("D:\\soft\\ceshi\\" + fileName + ".pdf");
//FileInputStream uploadFile = (FileInputStream) file.getInputStream();
// 获取文件输入流
FileInputStream inputStream = new FileInputStream(file);
//这个是已经填充完整的数据后上传至七牛云链接
String path = "http://" + upload(inputStream, fileName);
logger.info("上传至七牛云的合同路径==path==" + path);
return path;
}
public String upload(FileInputStream file, String fileName) throws QiniuException {
String token = auth.uploadToken(bucketName);
Response res = uploadManager.put(file, fileName, token, null, null);
if (!res.isOK()) {
throw new RuntimeException("上传七牛云出错:" + res);
}
return url + "/" + fileName;
}
public static void main(String[] args) {
try {
// 指定原始图片路径
File originalImage = new File("D:\\soft\\ceshi\\20230901204201606.png");
// 指定压缩后保存的目标路径
File compressedImage = new File("D:\\soft\\ceshi\\20230901204201606_result.png");
// 压缩和缩放图片
Thumbnails.of(originalImage)
.scale(0.1) // 缩放比例为50%
.outputQuality(0.9) // 图片质量为80%
.toFile(compressedImage);
System.out.println("图片压缩和缩放完成!");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* MultipartFile 转file
*
* @param multipartFile
* @return
* @throws IOException
*/
public static File convertMultipartFileToFile(MultipartFile multipartFile) throws IOException {
byte[] fileBytes = multipartFile.getBytes();
File tempFile = File.createTempFile("temp", null);
try (OutputStream outputStream = new FileOutputStream(tempFile)) {
outputStream.write(fileBytes);
}
return tempFile;
}
/**
* 根号https链接下载文档
*
* @param fileUrl
* @param localFilePath
* @throws IOException
*/
public static void downloadFile(String fileUrl, String localFilePath) throws IOException {
URL url = new URL(fileUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
BufferedInputStream inputStream = new BufferedInputStream(connection.getInputStream());
FileOutputStream outputStream = new FileOutputStream(localFilePath);
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
inputStream.close();
connection.disconnect();
}
}
注意:前端传过来的图片必须是透明的,否则合成的时候签名处会有边框