Я использую pdfbox для добавления изображения PNG в файл PDF в Java. Изображение добавляется в PDF-файл и отображается, но без цвета, только черный. Я изменил часть изображения на красный, но оно по-прежнему добавляется в PDF-файл как черное. Я ожидал, что если я изменю цвет изображения, оно также будет того же цвета в PDF-файле после того, как я добавил его с помощью поля PDF-файла, но, очевидно, это так. чего-то не хватает.
PDImageXObject pdImageStamp — это изображение, которое я изменил, чтобы иметь одну часть красного цвета, но если оно добавлено, оно отображается как черное.
Обратите внимание, что я использую pdfbox версии 2.0.8 и Java 8.
Вот мой код, используемый для добавления изображения.
private String addStampSignatureImageToPage(PDDocument pdDoc, PDPage pdPage,String stampPath ,String signaturePath, String locationOnPdf) throws Exception{
StandardFunctions stdClass = new StandardFunctions();
//Decode file settings
String [] fileSettings = locationOnPdf.split(",");
PDImageXObject pdImageStamp = null;
PDImageXObject pdImageSignature = null;
PDPageContentStream contentStream = null;
Matrix matrix = null;
if (fileSettings==null||fileSettings.length!=9)
{
//No Settings found do not add stamp
return "No file settings for location found, no stamp added";
}
int stampWidth = Integer.valueOf(fileSettings[0]);
int stampHeight = Integer.valueOf(fileSettings[1]);
int stampX = Integer.valueOf(fileSettings[2]);
int stampY = Integer.valueOf(fileSettings[3]);
int signatureWidth = Integer.valueOf(fileSettings[4]);
int signatureHeight = Integer.valueOf(fileSettings[5]);
int signatureX = Integer.valueOf(fileSettings[6]);
int signatureY = Integer.valueOf(fileSettings[7]);
int rotateDegree = Integer.valueOf(fileSettings[8]);
try{
//Define the stamp image
BufferedImage awtImage = ImageIO.read(new File(stampPath));
System.out.println("3");
//pdImageStamp = PDImageXObject.createFromFile(stampPath, pdDoc);
pdImageStamp = LosslessFactory.createFromImage(pdDoc, awtImage);
pdImageStamp.setWidth(stampWidth);
pdImageStamp.setHeight(stampHeight);
//Define the signature image
pdImageSignature = PDImageXObject.createFromFile(signaturePath, pdDoc);
pdImageSignature.setWidth(signatureWidth);
pdImageSignature.setHeight(signatureHeight);
//Page stream that we want to append our image to.
contentStream = new PDPageContentStream(pdDoc, pdPage,PDPageContentStream.AppendMode.APPEND,true);
matrix = new Matrix();
//If we want to rotate the image we apply it to our matrix to transform the page.
if (rotateDegree > 0)
{
matrix.rotate(Math.toRadians(rotateDegree));
contentStream.transform(matrix);
}
//When lanscape mode the y needs to be negative and atleast the size of the image width. the x should be positive at least the size of the image.
// x y w h
//contentStream.drawImage(pdImage, 100,-100, 100, 100);
//Add the stamp to the pdf
contentStream.drawImage(pdImageStamp, stampX, stampY, stampWidth, stampHeight);
//Add the signature to the pdf
contentStream.drawImage(pdImageSignature, signatureX, signatureY, signatureWidth, signatureHeight);
//Close stream
contentStream.close();
}
catch(Exception e)
{
stdClass.writeLog("Something crashed...Signature stamp image" + e.getMessage());
}
finally{
stdClass = null;
fileSettings = null;
pdImageStamp = null;
pdImageSignature = null;
contentStream = null;
matrix = null;
}
return "DONE";
}
Пример красного блока, который я хочу добавить в PDF.
Полученный PDF-файл я получаю после использования pdfbox.
Редактировать Чтобы помочь кому-то еще, борющемуся с той же проблемой. При дальнейшем исследовании проблемы я обнаружил, что после создания изображения не следует устанавливать ширину и высоту, используя следующий код.
pdImageStamp.setWidth(stampWidth);
pdImageStamp.setHeight(stampHeight);
Когда вы по какой-то причине используете это, цвет теряется, он добавляется только как черный без цвета. Лучше используйте функцию drawImage, чтобы установить ширину и высоту следующим образом.
contentStream.drawImage(pdImageStamp, stampX, stampY, stampWidth, stampHeight);
Даже если вы используете старую версию PDF-файла, у меня это работает для файлов .png.
Почему вы используете 2.0.8, а не 2.0.31? 2.0.8 от 2017 года. Это археологический проект?
Версия 2.0.8 очень старая (и если исправления будут применены к PDFBox 2, они будут применены к новейшей версии). Поэтому, пожалуйста, протестируйте еще раз с новейшей версией PDFBox 2.
Также укажите точную версию jdk8, введите «java -version». Кстати, отрицательный голос был не от меня, я поставил положительный, чтобы отменить это.
@TilmanHausherr Это старый проект, которому я пытаюсь помочь с версией jdk1.8.0_191. Я буду использовать новую версию pdfbox, как было предложено, чтобы попробовать и посмотреть, не является ли это ошибкой. Спасибо за голосование. Я также попробовал использовать другое изображение, просто чтобы убедиться, что оно не связано с моим файлом изображения. Кстати, это изображение .png, просто красный блок, который я сейчас использую для добавления, и оно теряет красный цвет, который добавляется как черный блок. Еще раз спасибо.
@TilmanHausherr Спасибо за вашу помощь, я обновился до 2.0.31, и теперь она работает. Наверное, это был глюк в старой версии. Вы можете добавить ответ, он примет его.
Приятно слышать. Вам также следует обновить свой jdk либо через oracle, если у вас есть контракт, либо загрузить Amazon Corretto docs.aws.amazon.com/corretto/latest/corretto-8-ug/…
Что касается вашего редактирования: действительно, методы PDImageXObject
setWidth
и setHeight
не меняют ширину и высоту отображаемого изображения, они меняют метаданные ширины и высоты ресурса растрового изображения. Поскольку вы не меняете само растровое изображение при в то же время это изменение обычно приводит к несоответствию растрового изображения и его метаданных. Это может привести к произвольным проблемам.
@mkl Я не знал об этом, но да, это вызывало проблемы с фактическим цветом и теми функциями, которые я не ожидал. На самом деле это вообще не ясно указано в справочной документации pdfbox.apache.org/docs/2.0.3/javadocs/org/apache/pdfbox/pdmodel/…
«На самом деле это вообще не ясно указано в справочной документации» - действительно, JavaDocs (из которого это генерируется) может предупредить пользователя не использовать эти методы для установки размера изображения на странице. @Тилман?
@Renier, ваше недавнее редактирование должно быть в ответе
@TilmanHausherr Я обновил твой ответ.
Какая бы ошибка ни была в версии 2.0.8, она больше не возникает в версии 2.0.31, которая является текущей версией на момент написания этой статьи, и ее можно загрузить через maven или по адресу https://pdfbox.apache.org/download .html
Также
После создания изображения не следует задавать ширину и высоту с помощью следующего кода.
pdImageStamp.setWidth(stampWidth);
pdImageStamp.setHeight(stampHeight);
PDImageXObject
методы setWidth
и setHeight
не меняют ширину и высоту отображаемого изображения, они изменяют метаданные ширины и высоты ресурса растрового изображения. Поскольку вы не меняете само растровое изображение одновременно, это изменение обычно будет привести к несоответствию растрового изображения и его метаданных. Это может привести к произвольным проблемам.
Лучше используйте функцию drawImage, чтобы установить ширину и высоту следующим образом.
contentStream.drawImage(pdImageStamp, stampX, stampY, stampWidth, stampHeight);
Даже если вы используете старую версию PDF-файла, это работает для файлов .png.
@TilmanHausherr Я обновил вопрос: pdfbox 2.0.8 и java 8, не знаю, почему отрицательный голос. Но спасибо за ваш ответ.