如何使用 PDFBox 将图像附加到 PDF 表单字段而不使现有签名失效?

问题描述 投票:0回答:1

用例:我正在开发一项功能,该功能需要将图像附加到 PDF,而不会使预先存在的数字签名失效。 PDF 应该有一个指定用于图像附件的表单字段,可以稍后填充。我想使用 PDFBox 来实现这个。

实现:由于 PDF 缺乏专用的图像表单字段,我使用 PDPushButton 作为解决方法,遵循这些资源中概述的方法;

此外,PDF 还包含签名表单字段。该过程包括首先对签名字段进行签名,然后将图像附加到 PDPushButton 字段。然而,这个序列导致签名无效。

这是将图像附加到 PDPushButton 的代码。

@SneakyThrows
public static void fillInitialField(String inputFilePath, String outputFilePath) {
    // Load input file
    PDDocument document = PDDocument.load(new File(inputFilePath));

    // Find and link the relevant signature field
    PDPushButton initial = PdfService.findInitial(document, "132323423180965");

    PDImageXObject pdImageXObject = PDImageXObject.createFromFile("initial.png", document);
    float width = 10 * pdImageXObject.getWidth();
    float height = 10 * pdImageXObject.getHeight();

    PDAppearanceStream pdAppearanceStream = new PDAppearanceStream(document);
    pdAppearanceStream.setResources(new PDResources());
    try (PDPageContentStream pdPageContentStream = new PDPageContentStream(document, pdAppearanceStream)) {
        pdPageContentStream.drawImage(pdImageXObject, 200, 300, width, height);
    }
    pdAppearanceStream.setBBox(new PDRectangle(width, height));

    List<PDAnnotationWidget> widgets = initial.getWidgets();
    for (PDAnnotationWidget pdAnnotationWidget : widgets) {

        PDAppearanceDictionary pdAppearanceDictionary = pdAnnotationWidget.getAppearance();
        if (pdAppearanceDictionary == null) {
            pdAppearanceDictionary = new PDAppearanceDictionary();
            pdAnnotationWidget.setAppearance(pdAppearanceDictionary);
        }

        pdAppearanceDictionary.setNormalAppearance(pdAppearanceStream);
    }
    initial.setReadOnly(true);

    // Save and close the document
    FileOutputStream fos = new FileOutputStream(outputFilePath);
    document.save(fos);
    document.close();
}

我创建了一个复制此问题的存储库,可以在此处找到:https://github.com/ContractSPAN/ImageFormFieldIssue

如何在 PDF 表单字段中实现图像附件,且不会使现有签名失效?我对实现此功能的替代方法持开放态度。

java pdf pdfbox e-signature
1个回答
0
投票

您在

save
结束时执行常规的
fillInitialField
。常规保存将重新排列和更改有符号字节范围。因此,您需要像在
saveIncremental
末尾那样执行
sign

请注意,pdfbox 2 中的

saveIncremental
要求您标记 (
setNeedToBeUpdated(true)
) 所有已更改的对象,包括从预告片分别通向它们的一系列对象。在签名的情况下,很多标记已经由 PDFBox 本身完成。但在您的
fillInitialField
方法中,您必须自己完成所有标记。

© www.soinside.com 2019 - 2024. All rights reserved.