При добавлении изображения в pdf-файл с помощью pdfbox изображение добавляется без цвета, часть изображения должна быть красной, но она черная

Я использую 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.

@TilmanHausherr Я обновил вопрос: pdfbox 2.0.8 и java 8, не знаю, почему отрицательный голос. Но спасибо за ваш ответ.

Renier 28.03.2024 09:55

Почему вы используете 2.0.8, а не 2.0.31? 2.0.8 от 2017 года. Это археологический проект?

Tilman Hausherr 28.03.2024 10:48

Версия 2.0.8 очень старая (и если исправления будут применены к PDFBox 2, они будут применены к новейшей версии). Поэтому, пожалуйста, протестируйте еще раз с новейшей версией PDFBox 2.

mkl 28.03.2024 10:48

Также укажите точную версию jdk8, введите «java -version». Кстати, отрицательный голос был не от меня, я поставил положительный, чтобы отменить это.

Tilman Hausherr 28.03.2024 10:49

@TilmanHausherr Это старый проект, которому я пытаюсь помочь с версией jdk1.8.0_191. Я буду использовать новую версию pdfbox, как было предложено, чтобы попробовать и посмотреть, не является ли это ошибкой. Спасибо за голосование. Я также попробовал использовать другое изображение, просто чтобы убедиться, что оно не связано с моим файлом изображения. Кстати, это изображение .png, просто красный блок, который я сейчас использую для добавления, и оно теряет красный цвет, который добавляется как черный блок. Еще раз спасибо.

Renier 28.03.2024 11:09

@TilmanHausherr Спасибо за вашу помощь, я обновился до 2.0.31, и теперь она работает. Наверное, это был глюк в старой версии. Вы можете добавить ответ, он примет его.

Renier 28.03.2024 11:35

Приятно слышать. Вам также следует обновить свой jdk либо через oracle, если у вас есть контракт, либо загрузить Amazon Corretto docs.aws.amazon.com/corretto/latest/corretto-8-ug/…

Tilman Hausherr 28.03.2024 13:27

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

mkl 02.04.2024 13:48

@mkl Я не знал об этом, но да, это вызывало проблемы с фактическим цветом и теми функциями, которые я не ожидал. На самом деле это вообще не ясно указано в справочной документации pdfbox.apache.org/docs/2.0.3/javadocs/org/apache/pdfbox/pdmo‌​del/…

Renier 02.04.2024 14:19

«На самом деле это вообще не ясно указано в справочной документации» - действительно, JavaDocs (из которого это генерируется) может предупредить пользователя не использовать эти методы для установки размера изображения на странице. @Тилман?

mkl 02.04.2024 14:39

@Renier, ваше недавнее редактирование должно быть в ответе

Tilman Hausherr 03.04.2024 13:32

@TilmanHausherr Я обновил твой ответ.

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

Ответы 1

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

Какая бы ошибка ни была в версии 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.

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