这两天公司开发需要对PDF增加特定图片,类似于电子印章效果,试了许多网上的方式,经过测试PDF只可以插入图片或者通过RSA实现专属签章,我觉得插入图片好用一些,效果如下:

这是定位了《盖章》最后一次出现的位置

放大后仔细观看可发现,印章处于黑线下面,这是因为此处插入的是图片,通过分层将图片置于底层,图片的背景必须为白色,不然图片背景也会显现出来,就像这样:

如果你的项目不需要考虑PDF可能更换背景色的情况(大部分PDF文件都是白色背景色),只是单纯得在指定位置加图片,那么你的图片可任意;若你像我一样做电子印章,且需要考虑背景色,那么你的图片背景色必须为白色,这是我在百度随便找的图片,仅供参考:

提示:若考虑背景色,在非白色下,不透明度为100%时,由于颜色太重,会盖住图片;我找了很久,暂未找到修改PDF背景色透明度的方法。

若上面的效果与你的项目的预期一致,那么下面就开始粘贴代码吧。

1. 依赖:

     <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13</version></dependency>

2. Java代码:

@Slf4j
public class ImageUtil {/*** pdf插入电子印章水印* @param templatePath 原pdf文件路径* @param targetPath 生成文件输出路径* @param imagePath 图片文件路径* @param keyword     关键字*/public static void imageWaterMark(String templatePath,String targetPath,String imagePath,String keyword) {try {File pdfFile = new File(templatePath);byte[] pdfData = new byte[(int) pdfFile.length()];FileInputStream inputStream = null;try {inputStream = new FileInputStream(pdfFile);inputStream.read(pdfData);} catch (IOException e) {log.error("PDF读流异常:" + e);} finally {if (inputStream != null) {try {inputStream.close();} catch (IOException e) {log.error("IO流关闭发生异常:" + e);}}}//指定关键字
//          String keyword = "计算机";List<float[]> positions = findKeywordPostions(pdfData, keyword);InputStream input = new FileInputStream(templatePath);if (positions != null && positions.size() > 0) {log.info("发现关键字总条数:" + positions.size());log.info("最后一次出现关键字的位置信息:页码=" + (int)positions.get(positions.size()-1)[0] + ",X轴=" + positions.get(positions.size()-1)[1] + ",Y轴=" + positions.get(positions.size()-1)[2]);PdfImage(targetPath,input,imagePath,(int)positions.get(positions.size()-1)[1],(int)positions.get(positions.size()-1)[2],(int) positions.get(positions.size()-1)[0]);}else {log.info("未发现关键字信息");}} catch (Exception e) {log.error("PDF插入图片发生意外异常:" + e);}  }/*** 添加电子签章水印* @param newPdfPath* @param srcPdfPath* @param imagePath* @param width* @param height* @param page*/private static void PdfImage(String newPdfPath,InputStream srcPdfPath,String imagePath, int width, int height, int page) {PdfReader pdfReader = null;PdfStamper pdfStamper = null;try {pdfReader = new PdfReader(srcPdfPath);    //获取最后一页(计算页面插入)
//          System.out.println("页数"+pdfReader.getNumberOfPages());FileOutputStream out = new FileOutputStream(newPdfPath);pdfStamper = new PdfStamper(pdfReader, out);//设置最后一页PdfContentByte pdfContentByte = pdfStamper.getUnderContent(page);//压缩图片float qrWidth = 42.75f / 35.4f * 72;Image qrcodeImage = Image.getInstance(imagePath);//设置图片宽高qrcodeImage.scaleToFit(qrWidth, qrWidth);//水印图片位置坐标qrcodeImage.setAbsolutePosition(width + 40, height - 45);//插入图片pdfContentByte.addImage(qrcodeImage);pdfStamper.close();}catch (Exception e) {log.error("PDF插入图片发生未知异常:" + e);}finally {if (pdfReader != null) {    pdfReader.close();}}}/*** 查找关键字集合* @param pdfData* @param keyword* @return* @throws IOException*/public static List<float[]> findKeywordPostions(byte[] pdfData, String keyword) {List<float[]> result = new ArrayList<>();List<PdfPageContentPositions> pdfPageContentPositions = getPdfContentPostionsList(pdfData);for (PdfPageContentPositions pdfPageContentPosition : pdfPageContentPositions) {List<float[]> charPositions = findPositions(keyword, pdfPageContentPosition);if (charPositions == null || charPositions.size() < 1) {continue;}result.addAll(charPositions);}return result;}/*** 读取文件内容* @param pdfData* @return*/private static List<PdfPageContentPositions> getPdfContentPostionsList(byte[] pdfData) {try {PdfReader reader = new PdfReader(pdfData);List<PdfPageContentPositions> result = new ArrayList<>();int pages = reader.getNumberOfPages();for (int pageNum = 1; pageNum <= pages; pageNum++) {PdfRenderListener pdfRenderListener = new PdfRenderListener(pageNum);//解析pdf,定位位置PdfContentStreamProcessor processor = new PdfContentStreamProcessor(pdfRenderListener);PdfDictionary pageDic = reader.getPageN(pageNum);PdfDictionary resourcesDic = pageDic.getAsDict(PdfName.RESOURCES);try {processor.processContent(ContentByteUtils.getContentBytesForPage(reader, pageNum), resourcesDic);} catch (Exception e) {reader.close();log.error("读取文件内容发生未知异常:" + e);}String content = pdfRenderListener.getContent();List<CharPosition> charPositions = pdfRenderListener.getcharPositions();List<float[]> positionsList = new ArrayList<>();for (CharPosition charPosition : charPositions) {float[] positions = new float[]{charPosition.getPageNum(), charPosition.getX(), charPosition.getY()};positionsList.add(positions);}PdfPageContentPositions pdfPageContentPositions = new PdfPageContentPositions();pdfPageContentPositions.setContent(content);pdfPageContentPositions.setPostions(positionsList);result.add(pdfPageContentPositions);}reader.close();return result;} catch (Exception e) {log.error("查找关键字发生未知异常:" + e);}}/*** 定位关键字位置* @param keyword* @param pdfPageContentPositions* @return*/private static List<float[]> findPositions(String keyword, PdfPageContentPositions pdfPageContentPositions) {List<float[]> result = new ArrayList<>();String content = pdfPageContentPositions.getContent();List<float[]> charPositions = pdfPageContentPositions.getPositions();for (int pos = 0; pos < content.length(); ) {int positionIndex = content.indexOf(keyword, pos);if (positionIndex == -1) {break;}float[] postions = charPositions.get(positionIndex);result.add(postions);pos = positionIndex + 1;}return result;}static class CharPosition{private int pageNum = 0;private float x = 0;private float y = 0;public CharPosition(int pageNum, float x, float y) {this.pageNum = pageNum;this.x = x;this.y = y;}public int getPageNum() {return pageNum;}public float getX() {return x;}public float getY() {return y;}@Overridepublic String toString() {return "[pageNum=" + this.pageNum + ",x=" + this.x + ",y=" + this.y + "]";}}private static class PdfPageContentPositions {private String content;private List<float[]> positions;public String getContent() {return content;}public void setContent(String content) {this.content = content;}public List<float[]> getPositions() {return positions;}public void setPostions(List<float[]> positions) {this.positions = positions;}}private static class PdfRenderListener implements RenderListener {private int pageNum;private StringBuilder contentBuilder = new StringBuilder();private List<CharPosition> charPositions = new ArrayList<>();public PdfRenderListener(int pageNum) {this.pageNum = pageNum;}public void beginTextBlock() {}public void renderText(TextRenderInfo renderInfo) {List<TextRenderInfo> characterRenderInfos = renderInfo.getCharacterRenderInfos();for (TextRenderInfo textRenderInfo : characterRenderInfos) {String word = textRenderInfo.getText();if (word.length() > 1) {word = word.substring(word.length() - 1, word.length());}Float rectangle = textRenderInfo.getAscentLine().getBoundingRectange();float x = (float)rectangle.getX();float y = (float)rectangle.getY();CharPosition charPosition = new CharPosition(pageNum, (float)x, (float)y);charPositions.add(charPosition);contentBuilder.append(word);}}public void endTextBlock() {}public void renderImage(ImageRenderInfo renderInfo) {}public String getContent() {return contentBuilder.toString();}public List<CharPosition> getcharPositions() {return charPositions;}}}

以上代码粘贴进你的项目,导下包就可以调用了,方法名:imageWaterMark();关键提醒:PDF若利用金山WPS打印过了,那样的PDF是无法识别文字的(打开PDF后,鼠标悬停PDF上变成小手就是被打印过了)。

以上内容就是本次分享的全部内容了,希望对正在观看的你有所帮助,*★,°*:.☆( ̄▽ ̄)/$:*.°★* 。

Java给PDF添加图片水印,且可以文字定位相关推荐

  1. Java使用Spire.Pdf实现PDF添加图片水印

    通过本文你将学到: Spire.Pdf是什么? 如何在项目中引入Spire.Pdf依赖? 项目中基于Spire.Pdf实现PDF添加图片水印? 一.Spire.Pdf是什么? 1.Spire.Pdf是 ...

  2. java pdf添加图片水印图片_Java 在PDF中添加文本水印、图片水印(基于Spire.Cloud.SDK for Java)...

    Spire.Cloud.SDK for Java提供了接口pdfWartermarkApi可用于添加文本水印addTextWartermark()和图片水印addImageWartermark()到P ...

  3. 用Java为视频添加图片水印(类似直播)

    文章目录 1.首先[下载nginx](http://nginx-win.ecsds.eu/download/) 2.[下载ffmpeg](https://pan.baidu.com/s/1LUWeVn ...

  4. .Net iTextSharp 给Pdf添加图片水印

    /// <summary>/// 设置pdf图片水印/// </summary>/// <param name="imgPath">水印图片路径 ...

  5. java pdf添加图片水印图片_Java 在PDF中添加文本水印、图片水印

    (推荐)方式1: 创建Maven项目程序,通过maven仓库下载导入.以IDEA为例,新建Maven项目,在xml文件中配置maven仓库路径,并指定spire.cloud.sdk的依赖,如下: co ...

  6. java -PDF添加文本水印与图片水印

    java pdf添加水印文本及图片文本 PDF文件添加文本水印: private static int interval = 30;public static voidwaterMark(String ...

  7. java为word、excel、pdf、ppt、图片添加图片水印(文字水印同理)

    使用idea开发,所需依赖如下: spire的下载.使用,代码中会给出网址.idea中选中右键,添加为库即可使用 <!--使用spire,导入的jar--> <dependency& ...

  8. java实现给PDF文件添加图片水印,java实现给PDF文件添加文字水印

    接上一篇,pdf跟tif 是一起做的 java实现 1.给PDF文件添加图片水印: public static void waterMark1(String inputFile,String outp ...

  9. 咖啡汪日志——JAVA导出pdf文件加水印 文字+图片、文字

    咖啡汪日志--JAVA导出pdf文件加水印 文字和图片.文字 hello,又大家见面了! 作为一只不是在戏精就是在戏精路上的哈士奇,今天要展示给大家的就是如何快捷地给pdf文件增加各种水印.嗷呜呜,前 ...

最新文章

  1. 微信小程序与uniapp中 px与rpx 相互转换
  2. gulp复制整个文件夹或文件到指定目录(包括拷贝单个文件)
  3. 机器学习相关——SVD分解
  4. 使用BizTalk Server常见问题处理
  5. 排序:插入排序与希尔排序
  6. 基于spring自动注入及AOP的表单二次提交验证
  7. js获得服务器时间并实时更新
  8. 0829 数据库的增删改查
  9. SHOP++ JTM2.5发布
  10. android 进度gif,Android NumberProgressBar:动态移动显示百分比进度的进度条
  11. word onenote_在Word和OneNote中求解和图形方程式
  12. 新蒂下午茶体基本版SentyTEA-Basic
  13. 好心情平台:30分钟就可改善抑郁情绪的运动处方
  14. png的格式及像素存储分析
  15. 黑白棋,又叫翻转棋(Reversi)、苹果棋或奥赛罗棋(Othello)。棋盘共有8行8列共64格。开局时,棋盘正中央的4格先置放黑白相隔的4枚棋子。双方轮流落子,只要落子和棋盘上任一枚己方的棋子
  16. 技术人如何管理时间?
  17. 中通股权曝光:阿里持股8.9% 赖梅松有77.7%投票权
  18. Qt编译报错:usr/include/c++/4.9/bits/stl_relops.:67: Parse error at “std“的解决办法
  19. 蓝桥杯赛前真题 Python组 Day 4
  20. MacOS下安装及配置Maven

热门文章

  1. 优乐商城05-1 项目环境搭建
  2. 【路径规划】无人机编队路径规划matlab源码
  3. successful sensing probability
  4. 第三、四章(顾客满意度分析)
  5. linux内存水印,Linux图片批量加水印
  6. Thinkpad笔记本无法从U盘启动,无法用光盘装win7的解决办法
  7. Zotero 安装+Zotero插件+ipad同步
  8. Android百度地图实例详解之仿摩拜单车APP(包括附近车辆、规划路径、行驶距离、行驶轨迹记录,导航等)
  9. c语言读取pdf文档,C语言文件读写技术..pdf
  10. Word2016多行公式在等号处对齐、自动编号和引用、公式居中且编号右对齐