当前位置: 首页 > news >正文

企业级-PDF图片水印

作者:fyupeng
技术专栏:☞ https://github.com/fyupeng
项目地址:☞ https://github.com/fyupeng/distributed-blog-system-api


留给读者

遇到签名,往往很无奈签名的位置、大小。

一、介绍

直接提供PDF路径和图片路径,以及输出路径,就可以完成需要的需求,关键字也可以作为参数传入,根据自行需求修改。

二、代码

public class PdfBuilderUtil {public static void imageWatermark(String inputPath, String outputPath,String imagePath) throws IOException, com.itextpdf.text.DocumentException {PdfReader reader = new PdfReader(inputPath);PdfStamper stamp = new PdfStamper(reader, new FileOutputStream(outputPath));PdfGState gs1 = new PdfGState();gs1.setFillOpacity(0.1f);InputStream imageIS = new FileInputStream(imagePath);Image image = Image.getInstance(IOUtils.toByteArray(imageIS));int n = reader.getNumberOfPages();InputStream inputStream = new FileInputStream(inputPath);PDDocument document = PDDocument.load(inputStream);for(int i=1;i<=n;i++){PdfContentByte pdfContentByte = stamp.getOverContent(i);// 默认图片水印大小,详见盖章右下角大小样例image.scalePercent(75f);// 默认图片水印横坐标,详见盖章右下角横坐标float absoluteX = 370;// 默认图片水印纵坐标,高度中间位置float absoluteY = (PageSize.POSTCARD.getHeight() - image.getScaledHeight())/2;float[] xyz = getKeyWords(reader, "盖章位置");if (xyz != null && xyz.length >= 3) {//新版文书absoluteY = xyz[1];} else {//旧版文书float[] oldXyz = getKeyWords(reader, "其他位置");if (oldXyz != null && oldXyz.length >= 3) {absoluteY = oldXyz[2]+300;}}// 读取图像文件PDFTextStripper stripper = new PDFTextStripper();stripper.setStartPage(i); // Page indexes are 1-based in PDFTextStripperstripper.setEndPage(i);String text = stripper.getText(document);if (!text.trim().isEmpty()) {image.setAbsolutePosition(absoluteX, absoluteY);pdfContentByte.addImage(image);}}inputStream.close();imageIS.close();stamp.close();reader.close();}/*** 根据关键字定位* @param pdfReader* @param keyWords* @return*/public  static float[] getKeyWords(PdfReader pdfReader, String keyWords) {float[] coordinate = null;int page = 0;try{int pageNum = pdfReader.getNumberOfPages();PdfReaderContentParser pdfReaderContentParser = new PdfReaderContentParser(pdfReader);CustomRenderListener renderListener = new CustomRenderListener();renderListener.setKeyWord(keyWords);for (page = 1; page <= pageNum; page++) {renderListener.setPage(page);pdfReaderContentParser.processContent(page, renderListener);coordinate = renderListener.getPcoordinate();if (coordinate != null) break;}} catch (IOException e) {e.printStackTrace();}return coordinate;}}

pdf签名帮助类

public class CustomRenderListener implements RenderListener{private float[] pcoordinate = null;private String keyWord;private int page;public int getPage() {return page;}public void setPage(int page) {this.page = page;}public float[] getPcoordinate(){return pcoordinate;}public String getKeyWord() {return keyWord;}public void setKeyWord(String keyWord) {this.keyWord = keyWord;}@Overridepublic void beginTextBlock() {}@Overridepublic void endTextBlock() {}@Overridepublic void renderImage(ImageRenderInfo arg0) {}@Overridepublic void renderText(TextRenderInfo textRenderInfo) {String text = textRenderInfo.getText();if (null != text && text.contains(keyWord)) {Float boundingRectange = textRenderInfo.getBaseline().getBoundingRectange();pcoordinate = new float[3];pcoordinate[0] = boundingRectange.x;pcoordinate[1] = boundingRectange.y;pcoordinate[2] = page;}}
}

三、总结

简洁、高效、精炼!

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【React】事件绑定、React组件、useState、基础样式
  • 如何理解ref toRef和toRefs
  • 问题记录-Spring Security- bean httpSecurity not found
  • HarmonyOS Web组件(二)
  • 低代码与传统编程:快速高质量构建系统的比较与方法
  • 全新UI自助图文打印系统小程序源码/自助云打印机前后端源码
  • IDEA工具中Java语言写小工具遇到的问题
  • 在RK3568上如何烧录MAC?
  • Windows 11 version 22H2 中文版、英文版 (x64、ARM64) 下载 (updated Jul 2024)
  • flutter 充电气泡
  • 安卓系统签名的制作与使用(SignApk.jar)踩坑记录
  • 【Vue3】从零开始编写项目
  • 今日总结:雪花算法,拉取在线用户
  • 深入理解Linux网络(二):UDP接收内核探究
  • tg小程序前端-dogs前端源码分析
  • [ JavaScript ] 数据结构与算法 —— 链表
  • [NodeJS] 关于Buffer
  • [微信小程序] 使用ES6特性Class后出现编译异常
  • 《网管员必读——网络组建》(第2版)电子课件下载
  • 【node学习】协程
  • 【知识碎片】第三方登录弹窗效果
  • Android单元测试 - 几个重要问题
  • Java 11 发布计划来了,已确定 3个 新特性!!
  • JavaScript 无符号位移运算符 三个大于号 的使用方法
  • javascript 总结(常用工具类的封装)
  • Laravel Telescope:优雅的应用调试工具
  • opencv python Meanshift 和 Camshift
  • redis学习笔记(三):列表、集合、有序集合
  • Redis字符串类型内部编码剖析
  • SOFAMosn配置模型
  • VUE es6技巧写法(持续更新中~~~)
  • 爱情 北京女病人
  • 包装类对象
  • 分类模型——Logistics Regression
  • 后端_ThinkPHP5
  • 前嗅ForeSpider采集配置界面介绍
  • 【运维趟坑回忆录 开篇】初入初创, 一脸懵
  • 进程与线程(三)——进程/线程间通信
  • 通过调用文摘列表API获取文摘
  • ​​​【收录 Hello 算法】9.4 小结
  • ​2021半年盘点,不想你错过的重磅新书
  • ​Redis 实现计数器和限速器的
  • ​Spring Boot 分片上传文件
  • # 20155222 2016-2017-2 《Java程序设计》第5周学习总结
  • # Swust 12th acm 邀请赛# [ E ] 01 String [题解]
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • (MTK)java文件添加简单接口并配置相应的SELinux avc 权限笔记2
  • (附源码)springboot 房产中介系统 毕业设计 312341
  • (十七)Flask之大型项目目录结构示例【二扣蓝图】
  • (五)关系数据库标准语言SQL
  • (转)大道至简,职场上做人做事做管理
  • (转)用.Net的File控件上传文件的解决方案
  • (转载)OpenStack Hacker养成指南
  • .bat批处理(七):PC端从手机内复制文件到本地
  • .net Application的目录