pdfbox - добавить визуальную подпись. Ошибка приведения COSObject

В org.apache.pdfbox.pdmodel.interactive.digitalsignature.SignatureOptions есть setVisualSignature метод. Я могу создать визуальную подпись из другого потока 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-файлом и новым изображением внешнего вида (которое я изменяю с помощью своего кода), у меня возникает эта ошибка:

Исключение в потоке "main" java.lang.ClassCastException: org.apache.pdfbox.cos.COSObject нельзя преобразовать в org.apache.pdfbox.cos.COSDictionary в org.apache.pdfbox.pdmodel.PDDocument.addSignature (PDDocument.java : 474)

Это образцы.

Что происходит? Я неправильно меняю изображения?


person Community    schedule 03.07.2013    source источник
comment
Лучше поздно, чем никогда, это будет исправлено в версии 1.8.10, см. PDFBOX-2767.   -  person Tilman Hausherr    schedule 21.04.2015


Ответы (1)


Разница между 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, «Потоки внешнего вида»). Отдельные обработчики аннотаций могут игнорировать эту запись и предоставлять свои собственные представления.

(Таблица 164 в ISO 32000- 1: 2008)

К сожалению, код, в котором возникает исключение, то есть PDDocument метод addSignature` в строке 474, выглядит так:

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

Таким образом, PDFBox здесь ожидает, что значение / AP будет прямым объектом словаря, а не ссылкой на косвенный объект словаря.

Я предполагаю, что ваша первая манипуляция заставляет PDFBox переписывать PDF так, как он считает себя лучшим (что, похоже, включает создание косвенных объектов словарей), а затем PDFBox имеет другие ожидания ...

Если вы выполнили свою первую манипуляцию как инкрементное обновление, а не полное переписывание, PDFBox может оставить словарь внешнего вида нетронутым.

person mkl    schedule 04.07.2013