如何使用PDFBox提取PDF文件中的数字签名可视化图片?
PDFBox 2.0.20 提取数字签名可视化图片操作指南
前置依赖配置
如果使用Maven管理项目,引入如下依赖即可:
<dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>2.0.20</version> </dependency> <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>fontbox</artifactId> <version>2.0.20</version> </dependency>
具体操作步骤
核心逻辑是遍历PDF的表单域,筛选出数字签名字段,再将字段的可视化外观渲染为图片输出,可运行示例代码如下:
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget; import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm; import org.apache.pdfbox.pdmodel.interactive.form.PDField; import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField; import org.apache.pdfbox.rendering.PDFRenderer; import org.apache.pdfbox.rendering.ImageType; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.List; public class ExtractSignatureImage { public static void main(String[] args) throws IOException { // 替换为实际PDF文件路径 File pdfFile = new File("test_signed.pdf"); PDDocument document = PDDocument.load(pdfFile); PDAcroForm acroForm = document.getDocumentCatalog().getAcroForm(); if (acroForm == null) { System.out.println("该PDF无表单域,不存在数字签名可视化内容"); document.close(); return; } int sigIndex = 0; // 遍历所有表单域筛选签名字段 for (PDField field : acroForm.getFields()) { if (field instanceof PDSignatureField) { PDSignatureField sigField = (PDSignatureField) field; List<PDAnnotationWidget> widgets = sigField.getWidgets(); for (PDAnnotationWidget widget : widgets) { // 按300DPI渲染签名所在页面,可按需调整DPI数值 PDFRenderer renderer = new PDFRenderer(document); int pageIndex = document.getPages().indexOf(widget.getPage()); BufferedImage fullPageImg = renderer.renderImageWithDPI(pageIndex, 300, ImageType.RGB); // 坐标换算:PDF默认72DPI,且原点在左下角,需转换为图片像素坐标 float scale = 300f / 72f; float x = widget.getRectangle().getLowerLeftX() * scale; float y = (widget.getPage().getMediaBox().getHeight() - widget.getRectangle().getUpperRightY()) * scale; float width = widget.getRectangle().getWidth() * scale; float height = widget.getRectangle().getHeight() * scale; // 裁剪得到签名区域图片并输出 BufferedImage sigImg = fullPageImg.getSubimage((int)x, (int)y, (int)width, (int)height); ImageIO.write(sigImg, "png", new File("signature_" + sigIndex + ".png")); sigIndex++; } } } document.close(); System.out.println("提取完成,共提取到" + sigIndex + "个签名可视化图片"); } }
常见注意事项
- 部分数字签名仅包含数字证书信息,无可视化外观,运行代码后不会生成对应图片,属于正常情况
- 若PDF有加密,需要先调用
document.openProtection(...)传入解密参数后再进行后续操作 - 渲染DPI可根据清晰度需求调整,值越高生成的图片分辨率越高、体积越大
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

