Проблемы совместимости настроек поворота Itext и Pdfbox

у меня есть PDF-файл, который создается с помощью itext, и когда я пытаюсь загрузить его с помощью pdfbox, он загружается в ландшафтном режиме, т.е. ширина и высота меняются местами (обычно ширина и высота PDF-файла, который находится в портретном режиме, составляет 595 и 842). (в пунктах) соответственно.) но при просмотре он в портретном режиме.

похоже, что 90 градусов — это портретное значение для PDF, созданного itext, а для pdfbox — 0 градусов. я попробовал повернуть PDF, но все равно безуспешно любая помощь будет оценена по достоинству.

ОБНОВЛЕНО:

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

void addImageOnlySignatureField(PDDocument pdDocument, PDPage pdPage, PDRectangle rectangle, PDSignature signature) throws IOException {
    PDAcroForm acroForm = pdDocument.getDocumentCatalog().getAcroForm();
    List<PDField> acroFormFields = acroForm.getFields();

    PDSignatureField signatureField = new PDSignatureField(acroForm);
    signatureField.setValue(signature);
    PDAnnotationWidget widget = signatureField.getWidgets().get(0);
    acroFormFields.add(signatureField);

    widget.setRectangle(rectangle);
    widget.setPage(pdPage);

    // from PDVisualSigBuilder.createHolderForm()
    PDStream stream = new PDStream(pdDocument);
    PDFormXObject form = new PDFormXObject(stream);
    PDResources res = new PDResources();
    form.setResources(res);
    form.setFormType(1);
    PDRectangle bbox = new PDRectangle(rectangle.getWidth(), rectangle.getHeight());

    form.setBBox(bbox);

    // from PDVisualSigBuilder.createAppearanceDictionary()
    PDAppearanceDictionary appearance = new PDAppearanceDictionary();
    appearance.getCOSObject().setDirect(true);
    PDAppearanceStream appearanceStream = new PDAppearanceStream(form.getCOSObject());
    appearance.setNormalAppearance(appearanceStream);
    widget.setAppearance(appearance);

    try (   PDPageContentStream cs = new PDPageContentStream(pdDocument, appearanceStream);
            InputStream imageResource = getClass().getResourceAsStream("/mkl/testarea/pdfbox2/content/Willi-1.jpg") )
    {
        cs.saveGraphicsState();
        Matrix m = new Matrix();
        m.rotate(90);
        cs.transform(m);
        PDImageXObject pdImage = PDImageXObject.createFromByteArray(pdDocument, ByteStreams.toByteArray(imageResource), "Willi");
        cs.addComment("This is a comment");
        cs.drawImage(pdImage, 0, 0, rectangle.getWidth(), rectangle.getHeight());
        cs.restoreGraphicsState();

    }

    pdPage.getAnnotations().add(widget);
    
    COSDictionary pageTreeObject = pdPage.getCOSObject(); 
    while (pageTreeObject != null) {
        pageTreeObject.setNeedToBeUpdated(true);
        pageTreeObject = (COSDictionary) pageTreeObject.getDictionaryObject(COSName.PARENT);
    }
}

Пожалуйста, поделитесь PDF-файлом и расскажите, как вы его просматривали.

Tilman Hausherr 11.03.2024 08:21

Я предполагаю, что в одном случае ОП использует книжный медиа-бокс и поворот страниц, а в другом случае — альбомный медиа-бокс. Любой вариант возможен с любой библиотекой.

mkl 11.03.2024 09:46

Предоставьте достаточно кода, чтобы другие могли лучше понять или воспроизвести проблему.

Community 11.03.2024 15:16

@TilmanHausherr это PDF-файл я просмотрел его в Adobe Reader, и когда я использую PDF-файл для добавления текстовых полей, я заметил, что все поля располагаются вертикально из-за его поведения в pdfbox. на данный момент я скорректировал размещение полей. но я просто хотел понять, ожидается ли такое поведение? поскольку я новичок в pdfbox, я хочу понять эти вещи

Ghost 12.03.2024 10:37

@mkl github код, который вы предоставили для добавления изображения в поле подписи (addImageOnlySignatureField), как мне настроить его для этого PDF-файла?

Ghost 12.03.2024 11:06

«как мне настроить его для этого PDF-файла?» - В addImageOnlySignatureField внешний вид генерируется в блоке try ( PDPageContentStream cs = ...). Добавьте инструкцию cs.transform в начало этого блока, которая противодействует повороту страницы.

mkl 12.03.2024 11:37

PDF-файл отображается в Adobe Reader точно так же, как в PDFBox: в портретном режиме. Ваша страница поворачивается на 90°, что усложняет добавление контента. Для аннотаций вы можете использовать вращение в PDAppearanceCharacteristicsDictionary для компенсации.

Tilman Hausherr 12.03.2024 11:41

спасибо @TilmanHausherr, я попробовал это для текстовых полей, это работает

Ghost 12.03.2024 14:07

@mkl, я обновил код в своем посте, не могли бы вы указать, что я делаю не так? Должен ли я использовать координаты осей X и Y из прямоугольника, который используется при размещении поля?

Ghost 12.03.2024 14:09

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

mkl 12.03.2024 17:19
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
10
79
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

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

Таким образом, исходный код (без учета поворота страниц)

try (   PDPageContentStream cs = new PDPageContentStream(pdDocument, appearanceStream);
        InputStream imageResource = getClass().getResourceAsStream("/mkl/testarea/pdfbox2/content/Willi-1.jpg") )
{
    PDImageXObject pdImage = PDImageXObject.createFromByteArray(pdDocument, ByteStreams.toByteArray(imageResource), "Willi");
    cs.addComment("This is a comment");
    cs.drawImage(pdImage, 0, 0, rectangle.getWidth(), rectangle.getHeight());
}

(CreateMultipleVisualizations вспомогательный метод addImageOnlySignatureField)

нужно изменить на что-то вроде этого:

try (   PDPageContentStream cs = new PDPageContentStream(pdDocument, appearanceStream);
        InputStream imageResource = getClass().getResourceAsStream("/mkl/testarea/pdfbox2/content/Willi-1.jpg") )
{
    Matrix matrix = new Matrix();
    boolean switchLengths = false;
    switch (pdPage.getRotation() % 360) {
    case 90:
        matrix.translate(rectangle.getWidth(), 0);
        matrix.rotate(Math.PI/2);
        switchLengths = true;
        break;
    case 180: //untested
        matrix.translate(rectangle.getWidth(), rectangle.getHeight());
        matrix.rotate(Math.PI);
        break;
    case 270: //untested
        matrix.translate(0, rectangle.getHeight());
        matrix.rotate(-Math.PI/2);
        switchLengths = true;
        break;
    }
    cs.transform(matrix);

    PDImageXObject pdImage = PDImageXObject.createFromByteArray(pdDocument, ByteStreams.toByteArray(imageResource), "Willi");
    cs.addComment("This is a comment");
    if (switchLengths)
        cs.drawImage(pdImage, 0, 0, rectangle.getHeight(), rectangle.getWidth());
    else
        cs.drawImage(pdImage, 0, 0, rectangle.getWidth(), rectangle.getHeight());
}

(CreateMultipleVisualizations вспомогательный метод addRotationAwareImageOnlySignatureField)

@Ghost "это сработало" - Отлично! Однако будьте осторожны: я тестировал только случай 90 ° (с вашим файлом примера). Код для 180° и 270° выглядит правильно, но он не проверен.

mkl 13.03.2024 07:19

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