Как прикрепить изображение к полю формы PDF, не делая недействительной существующую подпись с помощью PDFBox?

Вариант использования: я работаю над функцией, которая требует прикрепления изображения к 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 таким образом, чтобы это не делало недействительной существующую подпись? Я открыт для альтернативных подходов для достижения этой функциональности.

@KJ: в комментариях сейчас много материалов для ответов. Не могли бы вы переместить их в ответ?

halfer 13.04.2024 16:32

@KJ Спасибо за быстрый ответ. Я понимаю, что существует необходимость в улучшении работы подписи PDF. Хотя в настоящее время меня не очень беспокоят недостатки подписи PDF, поскольку это широко распространено в отрасли. Скорее я ищу способ реализовать это.

Shivam Malviya 14.04.2024 05:35
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
2
126
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Вы делаете обычный save в конце fillInitialField. Обычное сохранение переупорядочит и изменит диапазон байтов со знаком. Таким образом, вместо этого вам нужно будет поставить saveIncremental, как вы это делаете в конце sign.

Однако будьте осторожны: saveIncremental в pdfbox 2 требует от вас отметить (setNeedToBeUpdated(true)) все измененные объекты, включая последовательность объектов, ведущих к ним соответственно из трейлера. В случае подписания большая часть этой маркировки уже выполняется самим PDFBox. Но в вашем fillInitialField методе всю разметку вам придется делать самостоятельно.

Спасибо @mkl! Использование saveIncremental решает половину моей проблемы. Теперь прикрепленная подпись не становится недействительной. Однако прикрепленное к PDPushButton изображение не отображается. Без подписи я вижу прикрепленное изображение к PDPushButton. Я наблюдал эту проблему в Adobe PDF Reader. Ниже ссылка на pdf. drive.google.com/file/d/1S2N0D6DHycC1AxE3BggLKbkyJ7tcDOcB/… Спасибо за помощь!

Shivam Malviya 27.04.2024 11:24

Большая проблема заключается в том, что вы используете одно и то же имя для поля подписи и кнопки инициалов. Объекты полей с одинаковым именем представляют одно и то же абстрактное поле и, следовательно, должны иметь одинаковые записи, за исключением подробностей отображения.

mkl 30.04.2024 12:14

Добавлять поле формы не нужно, в большинстве населенных пунктов допускается дополнительный комментарий с печатью или вторая подпись в любом формате. Контракт просто формируется путем подписания двух поименованных сторон.

В основном в моем районе:

Согласно английскому законодательству, то, что представляет собой подпись, является гибким. Намерение человека может определить, заключили ли они обязательные соглашения или сделки. Многие платформы электронной подписи могут собрать достаточно доказательств, чтобы доказать намерение, если кто-то позже оспорит действительность контракта. Мы полагаем, что это включает в себя создание документа по английскому праву.

Электронным подписям не следует доверять ни при каких обстоятельствах.

Оба эти документа могут иметь точно такой же правовой статус, как и подписанный. Поскольку подпись в любом формате разрешена во многих юрисдикциях. Электронное использование цифрового хеша не должно быть препятствием для намерения заключить контракт.

Влажная подпись в виде изображения может быть применена от имени любого другого лица и образовать обязывающее соглашение до тех пор, пока одна или другая сторона не откажется от него, уведомив об этом другую. Это во многом процесс ОТКАЗА, подобный тому, как король Иоанн восемь веков назад заявил, что его печать, поставленная для него на Великой Хартии Свободы, не является обязательной в глазах его Бога, и поэтому хартия была аннулирована Папой Иннокентием III!

Итак, каковы требования? Ну, технически, поскольку это «политика отказа», обе подписи могут быть помечены как недействительные и при этом иметь юридическую силу в качестве намерения обеих сторон, поэтому электронная действительность не является ни доказательством, ни отрицанием намерения.

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