Itext7 pdfbuttonformfield метод setimage не работает с подписанным pdf-файлом

Я использую java-библиотеку itext7, как показано ниже, чтобы добавить PdfButtonFormField в существующий PDF-файл:

String src = "sample.pdf";
String dest = "acro_sample_empty_fields.pdf";


PdfDocument pdf = new PdfDocument(new PdfReader(src), new     PdfWriter(dest));
PdfAcroForm form = PdfAcroForm.getAcroForm(pdf, true);
PdfButtonFormField button = PdfFormField.createPushButton(pdf, new Rectangle(Integer.parseInt(control.xCord), Integer.parseInt(control.yCord),Integer.parseInt(control.width), Integer.parseInt(control.height)), control.name, control.value);

form.addField(button, page);

String resource = "sample.png";
button.setImage(resource);

После этого я использую следующий код для заполнения формы, как показано ниже:

String src = "1540982441_313554925_acro_sample_empty_fields_signedFinal.pdf";
String dest = "acro_sample_filled_fields.pdf";

PdfReader reader = new PdfReader(src);
File output = new File(dest);

OutputStream outputStream = new FileOutputStream(output);
PdfDocument document = new PdfDocument(reader,
                    new PdfWriter(outputStream),
                    new StampingProperties().useAppendMode());
PdfAcroForm form = PdfAcroForm.getAcroForm(document, true);
Map<String, PdfFormField> fields = form.getFormFields();

String resource = "sample_test.png";
((PdfButtonFormField)fields.get(control.name)).setImage(resource);

На нормальном pdf все работает нормально. Но если я поставлю цифровую подпись на созданный pdf файл, а затем попытаюсь его заполнить. тогда изображение настроено неправильно. Для обычного PDF-файла изображение на кнопке изменяется, как и ожидалось. Но на pdf с цифровой подписью изображение не устанавливается.

Я пытался найти это в Google, но пока не повезло. Любая помощь будет оценена по достоинству. Заранее спасибо.

Спасибо за редактирование @Daniel

Gautam Anand 31.10.2018 13:32
«Но если я поставлю цифровую подпись на созданный PDF-файл, а затем попытаюсь заполнить его. Изображение будет настроено неправильно». - Пожалуйста, поделитесь образцом PDF до и после подписания. Я ожидаю, что подпись будет нарушена вашим кодом, но изображение кнопки будет установлено.
mkl 31.10.2018 19:46

Связано, но с использованием iText 5: этот ответ

mkl 31.10.2018 19:47

Спасибо за ответ @mkl. Я также ожидал того же, что и вы упомянули, что подпись будет сломана, но изображение будет установлено. Я изучу ответ, который вы указали для itext5, и посмотрю, поможет ли он мне. В противном случае я поделюсь всеми твоими pdf-файлами. 1> сразу после добавления полей acro, 2> после его подписания. 3> после изменения подписанного pdf.

Gautam Anand 01.11.2018 07:27

@mkl Я попытался перенести упомянутый вами код для itext5, но мне это не удалось. Ссылка на 3 PDF-файла: [ссылка] jmp.sh/JesPwyE

Gautam Anand 01.11.2018 08:32

@mkl спасибо за помощь, я перенес весь свой код на itext5 и смог реализовать ваш код. Вся помощь очень ценится

Gautam Anand 01.11.2018 12:04

Посмотрю, скорее всего завтра, сегодня у нас праздник и у меня только смартфон под рукой.

mkl 01.11.2018 14:32

Это действительно интересно. Если вы посмотрите файл (подписанный, изображение изменено) в Adobe Acrobat, вы действительно увидите исходное изображение. Но если вы посмотрите файл в Chrome или Foxit, вы увидите новое изображение. Похоже, это особая функция Adobe ...

mkl 05.11.2018 17:17
"вы действительно можете увидеть исходное изображение", по крайней мере, это случилось с моими тестовыми файлами. Используя ваш подписанный тестовый файл в качестве основы, я получил пустую кнопку ... странно ...
mkl 05.11.2018 18:20
0
9
583
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я протестировал код в этом ответе с помощью подписанный, но незаполненный PDF-файл, которым вы поделились. Однако, поскольку вы не поделились образцом изображения, я использовал свое собственное.

Более точное наблюдение

Ты говоришь

Everything works fine for a normal pdf. But if i digitally sign the created pdf and then try to fill it. then the image is not set properly. For a normal pdf the image on the push button is changed as expected. But on the digitally signed pdf the image is not set.

Это не совсем так, изображение является установлено, но не все программы просмотра PDF Показать его.

Подробно: если вы установите изображение в подписанном PDF-файле с помощью своего кода, Adobe Reader действительно покажет просто серую рамку.

Adobe Reader Screen shot

но другие программы просмотра PDF, например Foxit или встроенная программа просмотра Chrome, показывать заменяющее изображение

Foxit screen shot

Таким образом, изображение устанавливается и для PDF-файла с цифровой подписью. Реальная проблема в том, что Adobe Reader не отображает его!

Причина

После некоторого анализа и некоторых отвлекающих маневров причина проблемы заключается в том, что если Adobe Reader отображает PDF-файл с измененным внешним видом кнопки AcroForm и

  • PDF-файл не подписан, тогда Adobe Reader просто использует обновленный поток внешнего вида; но если
  • PDF-файл подписан, затем Adobe Reader пытается игнорировать обновленного потока внешнего вида и внешнего вида построить новый из информации о характеристиках внешнего вида.

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

iText действительно создает словарь характеристик внешнего вида для кнопки (поэтому Adobe Reader предполагает, что он может игнорировать обновленный внешний вид и может создать новый на основе этого словаря), но, к сожалению, не добавляет к нему некоторую информацию, относящуюся к кнопке, ни при создании кнопки, ни при смене кнопки. В частности, это касается следующих двух записей:

I stream (Optional; push-button fields only; shall be an indirect reference) A form XObject defining the widget annotation’s normal icon, which shall be displayed when it is not interacting with the user.

TP integer (Optional; push-button fields only) A code indicating where to position the text of the widget annotation’s caption relative to its icon:

0 No icon; caption only

1 No caption; icon only

2 Caption below the icon

3 Caption above the icon

4 Caption to the right of the icon

5 Caption to the left of the icon

6 Caption overlaid directly on the icon

Default value: 0.

(ISO 32000-2, Таблица 192 - Записи в словаре характеристик внешнего вида)

Поскольку iText не предоставляет значение TP, включается Значение по умолчанию, и Adobe Reader создает внешний вид кнопки с надписью «Без значка; только заголовок». Поскольку заголовок не определен, результатом является серая рамка.

Обход

Самый простой способ - удалить весь словарь характеристик внешнего вида во время обновления изображения, т. Е. Заменить

((PdfButtonFormField)fields.get(control.name)).setImage(resource);

к

PdfButtonFormField button = (PdfButtonFormField)fields.get(control.name);
button.setImage(resource);
if (button.getPdfObject().containsKey(PdfName.MK)) {
    button.setModified();
    button.getPdfObject().remove(PdfName.MK);
}

(Вспомогательный метод SetButtonImagesetLikeGautamAnandImproved)

Теперь Adobe Reader не находит никаких характеристик внешнего вида и, следовательно, не может игнорировать обновленный поток внешнего вида.

Исправление

В качестве альтернативы мы можем добавить отсутствующие записи характеристик внешнего вида, например нравится:

PdfButtonFormField button = (PdfButtonFormField)fields.get(control.name);
button.setImage(resource);
PdfWidgetAnnotation widget = button.getWidgets().get(0);
PdfDictionary characteristics = widget.getAppearanceCharacteristics();
if (characteristics != null) {
    characteristics.setModified();
    characteristics.put(PdfName.I, widget.getNormalAppearanceObject());
    characteristics.put(PdfName.TP, new PdfNumber(1));
}

(Вспомогательный метод SetButtonImagesetLikeGautamAnandImproved2)

Однако результат выглядит немного иначе:

Adobe Reader Screen shot

Как видите, вокруг изображения есть небольшая рамка. Скорее всего, вы можете заставить его исчезнуть, настроив соответствующие другие характеристики.

Другие вопросы по теме