у меня есть 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);
}
}
Я предполагаю, что в одном случае ОП использует книжный медиа-бокс и поворот страниц, а в другом случае — альбомный медиа-бокс. Любой вариант возможен с любой библиотекой.
Предоставьте достаточно кода, чтобы другие могли лучше понять или воспроизвести проблему.
@TilmanHausherr это PDF-файл я просмотрел его в Adobe Reader, и когда я использую PDF-файл для добавления текстовых полей, я заметил, что все поля располагаются вертикально из-за его поведения в pdfbox. на данный момент я скорректировал размещение полей. но я просто хотел понять, ожидается ли такое поведение? поскольку я новичок в pdfbox, я хочу понять эти вещи
@mkl github код, который вы предоставили для добавления изображения в поле подписи (addImageOnlySignatureField), как мне настроить его для этого PDF-файла?
«как мне настроить его для этого PDF-файла?» - В addImageOnlySignatureField
внешний вид генерируется в блоке try ( PDPageContentStream cs = ...)
. Добавьте инструкцию cs.transform
в начало этого блока, которая противодействует повороту страницы.
PDF-файл отображается в Adobe Reader точно так же, как в PDFBox: в портретном режиме. Ваша страница поворачивается на 90°, что усложняет добавление контента. Для аннотаций вы можете использовать вращение в PDAppearanceCharacteristicsDictionary для компенсации.
спасибо @TilmanHausherr, я попробовал это для текстовых полей, это работает
@mkl, я обновил код в своем посте, не могли бы вы указать, что я делаю не так? Должен ли я использовать координаты осей X и Y из прямоугольника, который используется при размещении поля?
«Я обновил код в своем посте, не могли бы вы указать, что я делаю не так?» - смотрите мой ответ.
Как уже упоминалось в комментариях, при формировании внешнего вида подписи необходимо противодействовать повороту страницы. И при повороте внешнего вида для этого не следует забывать, что чистое вращение также приводит к повороту содержимого за пределы ограничивающей рамки внешнего вида. Значит, тоже приходится переводить.
Таким образом, исходный код (без учета поворота страниц)
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° выглядит правильно, но он не проверен.
Пожалуйста, поделитесь PDF-файлом и расскажите, как вы его просматривали.