
本文详解如何利用 openpdf 的 `pdfstamper` 与页面覆层(over content)机制,将印章等图像精确、动态地叠加在 pdf 文本之上,支持绝对定位与分页适配,满足合同签署等实际业务需求。
OpenPDF(iText 2.x 的开源分支)的 Image 类确实不提供“浮于文字上方”的原生布局模式——其 ALIGNMENT 常量(如 UNDERLYING、TEXTWRAP)仅控制图像与段落流的相对关系,且全部作用于文档内容流(underlying 或 inline)中,无法实现视觉上的“图层覆盖”。若需实现类似电子合同中动态加盖印章的效果(即图像始终显示在文字顶层,位置可编程控制),必须跳出 Document.add() 的流式布局范式,转而采用底层图形操作。
核心思路是:使用 PdfStamper 打开已有 PDF,并向指定页面的“覆层(Over Content)”中直接绘制图像。覆层(getOverContent(pageNumber))是 PDF 页面中独立于主内容流的绘图层,所有写入其中的对象(文本、图像、矢量图形)均会渲染在原始内容之上,天然满足“悬浮”需求。
以下是完整实现步骤与示例代码:
✅ 步骤一:加载 PDF 并获取覆层
String src = "contract.pdf"; String dest = "contract_with_seal.pdf"; PdfReader reader = new PdfReader(src); PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest)); // 获取第1页的覆层(索引从1开始) PdfContentByte over = stamper.getOverContent(1);
✅ 步骤二:加载并定位印章图像
Image seal = Image.getInstance("seal.png");
seal.scaleAbsolute(120f, 120f); // 建议预设尺寸,避免缩放失真
// 设置绝对坐标(单位:用户空间,默认左下为原点)
// x = 距左边界距离,y = 距下边界距离(注意:非距顶部!)
float x = 400f; // 示例:距左侧400单位
float y = 600f; // 示例:距底部600单位 → 实际位于页面中上区域
seal.setAbsolutePosition(x, y);✅ 步骤三:将图像写入覆层
over.addImage(seal);
✅ 步骤四:关闭资源
stamper.close(); reader.close();
⚠️ 关键注意事项
- 坐标系理解:PDF 用户坐标系原点在左下角,Y 值增大方向向上。若需按“距顶部 N 点”定位(更符合直觉),请用 y = pageSize.getHeight() - topMargin - imageHeight 计算。
- 分页动态适配:PdfStamper 支持遍历所有页面(reader.getNumberOfPages()),结合 reader.getPageSize(pageNum) 获取每页尺寸,即可根据内容逻辑(如关键字位置、段落高度)动态计算印章坐标。
- 图像格式兼容性:推荐使用 PNG(支持透明通道)或 JPEG;避免使用含复杂 ICC 配置的图像,以防渲染异常。
- 性能与内存:PdfStamper 会将整个 PDF 加载进内存,处理超大文件时建议分批操作或启用 setFullCompression()。
- 与 UnderContent 的区别:勿误用 getUnderContent() —— 它位于文字下方,效果相反。
? 进阶提示:基于文本定位印章
若印章需对齐某段落(如“甲方签字处”),可先用 PdfReader 提取文本位置(需配合 LocationTextExtractionStrategy 或第三方工具如 pdfbox 定位),再据此计算覆层坐标,实现真正的“语义化盖章”。
综上,OpenPDF 中实现图像悬浮并非通过 Image 的对齐常量,而是借助 PdfStamper 的分层渲染能力。掌握 OverContent 这一机制,不仅能实现印章功能,还可拓展至水印、动态签名框、浮动图标等所有需要图层覆盖的场景。










