关于加载水印PDF、图片以及压缩包格式文件【把博客当工作记录】

news/2024/10/22 16:39:36/

写这篇文章的目的是让大家都可以学到东西,核心代码中列出了处理思维和调用方法,业务代码已经过滤掉了,希望大家不要做crud程序员!!要思考。。。该博客不懂时可联系下方。
在这里插入图片描述

1、流程图如下

策略处理图片

2、策略描述

实现方式:
设计模式:父策略调动子策略
业务理念:在不影响原有业务的前提下增加优化
报错机制:当加载logo时报错,直接返回原有文件地址
业务分支:
1、pdf策略:
使用PDDocument处理pdf,主要流程如下
①生成下角PDF(自适应源文件大小)
②拉取源文件到本地
③转换PDF到JPG并合并文件(pdf直接合并会自动分页)
④将转换后的文件重新生成PDF
2、图片策略:
①生成下角PDF(自适应源文件大小)
②拉取源文件到本地
③转换pdf文件成图片并同源文件合并
3、压缩包策略:
根据压缩包的格式走不通的解压 压缩方式
①拉取压缩包到本地
②生成下角PDF
③解压压缩包并将生成的PDF放入
④压缩文件目录

剩余问题(优化性问题):
1、效率问题: 第一次下载文件时,因未处理过需要走策略模式,因处理步骤较多可能会很慢。
2、自适应问题:PDF自适应时会将清晰度降低,目前不走自适应

3、核心代码模块

一、图片格式处理

①生成左小角文件

java">public void createJpgWithSize(String filePath, float width, float height, Contact contact) {try (PDDocument document = new PDDocument();FileOutputStream fio = new FileOutputStream(new File(filePath))) {// 创建具有指定大小的页面PDPage page = new PDPage(new PDRectangle(width, height));try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) {// 设置字体和颜色File fontFile = new File("/data/config/easybii/simhei.ttf");PDType0Font font = PDType0Font.load(document, fontFile);contentStream.setFont(font, 22);contentStream.setNonStrokingColor(Color.black);String phone = " ";if (StringUtils.isNotBlank(contact.getTelephone())) {phone += contact.getTelephone();}if (StringUtils.isNotBlank(contact.getTelephone1())) {phone += "  " + contact.getTelephone();}// 写入文字contentStream.beginText();contentStream.newLineAtOffset(20, 15);contentStream.showText("报价联系人: " + contact.getName() + phone);contentStream.endText();}// 将页面添加到文档中document.addPage(page);// 保存文档document.save(fio);} catch (IOException e) {e.printStackTrace();}}

②将pdf文件转化为jpg

java">  public void convertPDDocumentToImage(String pdfPath, String outputImagePath) {try (PDDocument document = PDDocument.load(new File(pdfPath))) {PDFRenderer renderer = new PDFRenderer(document);BufferedImage image = renderer.renderImageWithDPI(0, 300); // 0 表示第一页,300 是 DPIjavax.imageio.ImageIO.write(image, "jpg", new File(outputImagePath));} catch (IOException e) {e.printStackTrace();}}

③压缩尺寸

java"> /*** 压缩尺寸** @param sourceImagePath* @param targetImagePath* @param targetWidth* @param targetHeight*/public void resizeJpg(String sourceImagePath, String targetImagePath, float targetWidth, float targetHeight) {try {BufferedImage sourceImage = ImageIO.read(new File(sourceImagePath));float sourceWidth = sourceImage.getWidth();float sourceHeight = sourceImage.getHeight();double scaleX = (double) targetWidth / sourceWidth;double scaleY = (double) targetHeight / sourceHeight;double scale = Math.min(scaleX, scaleY);int newWidth = (int) (sourceWidth * scale);int newHeight = (int) (sourceHeight * scale);BufferedImage resizedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);Graphics2D graphics2D = resizedImage.createGraphics();graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);graphics2D.drawImage(sourceImage, 0, 0, newWidth, newHeight, null);graphics2D.dispose();ImageIO.write(resizedImage, "jpg", new FileOutputStream(new File(targetImagePath)));} catch (IOException e) {e.printStackTrace();}}

④合并俩个图片

java">/*** 将俩张图片合并为一张图片** @param image1Path* @param image2Path* @param mergedImagePath*/public String mergeJpgImages(String image1Path, String image2Path, String mergedImagePath) {try {ImageInputStream input1 = ImageIO.createImageInputStream(new File(image1Path));ImageReader reader1 = ImageIO.getImageReaders(input1).next();reader1.setInput(input1);BufferedImage image1 = reader1.read(0);ImageInputStream input2 = ImageIO.createImageInputStream(new File(image2Path));ImageReader reader2 = ImageIO.getImageReaders(input2).next();reader2.setInput(input2);BufferedImage image2 = reader2.read(0);int width = Math.max(image1.getWidth(), image2.getWidth());int height = image1.getHeight() + image2.getHeight();BufferedImage mergedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);// 绘制第一张图片mergedImage.getGraphics().drawImage(image1, 0, 0, null);// 绘制第二张图片在第一张图片下方mergedImage.getGraphics().drawImage(image2, 0, image1.getHeight(), null

http://www.ppmy.cn/news/1505341.html

相关文章

【电商API接口项目实战分享】项目实战案例一:电商平台零售数据分析

本文以真实案例,带领大家一起学习如何搭建电商零售的用户画像。 “项目介绍” 此次项目数据来自Kaggle,包含了2010年12月1日至2011年12月9日在英国注册的非实体网上零售发生的所有交易。 字段如下: Invoice: 订单编号,每笔交易有6个整数。 …

华为校招机试 - 电影知识图谱和查询系统(20240605)

题目描述 你需要构建一套电影知识图谱和查询系统。 给定一个包含 N 部电影的数据集,每部电影用一个从 1 到 N 的整数编码,以及电影的导演、主演和类型等信息。 你的任务是,根据数据集构建一个电影知识图谱,并实现一个查询系统,可以根据用户的输入精确匹配(大小写敏感)…

【Python机器学习】支持向量机——利用完整platt SMO算法加速优化

在几百个数据点组成的小规模数据集上,简化版SMO算法的运行是没有什么问题,但是在更大的数据集上的运行速度就会变慢。完整版的platt SMO算法应用了一些能够提速的启动方法。 platt SMO算法时通过一个外循环来选择第一个alpha值的,并且其选择…

【Unity/XLua】xlua自带教程示例分析(二)—— 使用C#控制Lua生命周期函数并为其注入Unity物体依赖

文章目录 第一步 创建C#类LuaBehaviour,负责控制Lua的生命周期函数,创建Lua文件,内部提供所需生命周期函数和局部变量第二步 准备C#变量第三步 Awake函数初始化 第一步 创建C#类LuaBehaviour,负责控制Lua的生命周期函数&#xff0…

二分查找法

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…

STM32常见的下载方式有三种

经过对比,推荐使用 SWD下载,只需要一个仿真器(如jLINK、ST LINK、 CMSIS DAP 等),比较方便。 不推荐使用串口下载(速度慢、无法仿真和调试)和 JTAG 下载(占用 IO 多)。

贪心算法part03

134 加油站 在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。 如果你可以绕环路行…

SocketIO推送连接后,收不到服务端推送数据问题分析

重点需要注意前端和后端的SocketIO的版本&#xff0c;socketio在2.0.x才开始支持4.0协议。 可以看https://mvnrepository.com/artifact/com.corundumstudio.socketio/netty-socketio&#xff0c;引用最新版本。 <dependency><groupId>com.corundumstudio.socketi…