0

org.apache.pdfbox.pdmodel.interactive.digitalsignature.SignatureOptionssetVisualSignature方法。我可以从其他具有视觉签名外观的 pdf 流创建视觉签名(以复制外观)。

1)我创建了一个签名外观pdf,并使用该setVisualSignature()方法,我设法复制了视觉签名。一切正常;

2)我从 PDFBox 更改视觉签名(更改图像)。获取 COSObject:

Iterator<Entry<COSObjectKey, Long>> xrefEntriesIt = doc.getDocument()
        .getXrefTable().entrySet().iterator();
while (xrefEntriesIt.hasNext()) {
    COSObject object = doc.getDocument().getObjectFromPool(
            xrefEntriesIt.next().getKey());
    if (object.getDictionaryObject(COSName.SUBTYPE) == COSName.IMAGE) {
        changeImage(object, doc);
    }
}

并更改图像:

private static void changeImage(COSObject obj, PDDocument doc) {

    PDXObjectImage imageInPdf =
        (PDXObjectImage) PDXObject.createXObject((COSStream) obj.getObject());

    File inputFile = new File("/new_SIGNATURE_IMG.jpg");
    PDXObjectImage newImage = new PDJpeg(doc, new FileInputStream(inputFile));
    imageInPdf.getCOSStream().replaceWithStream(newImage.getCOSStream());
    doc.save("/new.pdf");
}

一切正常。

3)当我setVisualSignature()用新的pdf和新的外观图像(我用我的代码改变)调用方法时,我有这个错误:

线程“主”java.lang.ClassCastException 中的异常:org.apache.pdfbox.cos.COSObject 无法在 org.apache.pdfbox.pdmodel.PDDocument.addSignature(PDDocument.java 中转换为 org.apache.pdfbox.cos.COSDictionary :474)

那是样品

怎么了?我是否错误地更改了图像?

4

1 回答 1

0

template.pdf和的区别在于CHANGED_TEMPLATE.pdf前者中的签名字段字典包含其外观流字典作为直接对象:

9 0 obj
<< [...] /AP<</N 8 0 R>>>>
endobj

而在后一个中,外观流字典是仅从签名字段字典中引用的间接对象:

5 0 obj
<<
[...]
/AP 10 0 R
>>
[...]
10 0 obj
<<
/N 15 0 R
>>

这完全没问题,PDF规范通常不要求它是直接的:

AP字典(可选;PDF 1.2)外观字典,指定注释应如何在页面上以视觉方式呈现(参见 12.5.5,“外观流”)。单个注释处理程序可能会忽略此条目并提供自己的外观。

( ISO 32000-1:2008中的表 164 )

不幸的是,发生异常的代码,即第PDDocument474 行中的方法 addSignature ,如下所示:

PDAppearanceDictionary ap = 
    new PDAppearanceDictionary((COSDictionary)cosBaseDict.getItem(COSName.AP));

因此,这里的 PDFBox 期望/AP值是直接字典对象,而不是对间接字典对象的引用。

我假设您的第一次操作使 PDFBox 以它认为最好的方式重写 PDF(这似乎包括制作字典间接对象),然后 PDFBox 有其他期望......

如果您将第一次操作作为增量更新而不是完全重写,PDFBox 可能会保持外观字典不变。

于 2013-07-04T11:31:00.817 回答