Java – Empty page issues when adding images to PDF using Apache PDFBox

Empty page issues when adding images to PDF using Apache PDFBox… here is a solution to the problem.

Empty page issues when adding images to PDF using Apache PDFBox

I’m using this code: https://www.tutorialspoint.com/pdfbox/pdfbox_inserting_image.htm

Help me add an image to an existing PDF. The problem is that the file it creates is a blank page with only images on it.

Here is my code :

public void signPDF(PdfDTO pdfDTO) throws IOException{
        Loading an existing document
        File file = new File(getAbsolutePdfPath(pdfDTO));
        PDDocument doc = PDDocument.load(file);

Retrieving the page
        PDPage page = doc.getPage(0);

a test to ensure the doc is loading correctly
        PDDocument testDoc = new PDDocument();
        testDoc.addPage(page);
        testDoc.save("C:" + File.separator + "Users" + File.separator + "kdotson" + File.separator + "Documents" + File.separator + "test.pdf");
        testDoc.close(); this file is good so I know the doc is loading correctly

Creating PDImageXObject object
        PDImageXObject pdImage = PDImageXObject.createFromFile("C://test_images/signature.pdf", doc);

creating the PDPageContentStream object
        PDPageContentStream contents = new PDPageContentStream(doc, page);

Drawing the image in the PDF document
        contents.drawImage(pdImage, 0, 0);

Closing the PDPageContentStream object
        contents.close();

Saving the document
        doc.save(new File(getSignedPdfLocation(pdfDTO))); the created file has the image on it, so I know the image is loading correctly

Closing the document
        doc.close();
    }

As far as I know, what I’m doing should work and I’m not getting any errors, so what?

Solution

Also check the JavaDocs and source code of the library you are trying to use. You create a PDPageContentStream:

PDPageContentStream contents = new PDPageContentStream(doc, page);

According to the record, this conductor overrides all existing content streams for this page:

/**
 * Create a new PDPage content stream. This constructor overwrites all existing content streams
 * of this page.
 *
 * @param document The document the page is part of.
 * @param sourcePage The page to write the contents to.
 * @throws IOException If there is an error writing to the page contents.
 */
public PDPageContentStream(PDDocument document, PDPage sourcePage) throws IOException

Therefore, you must use a different constructor to preserve the current page content, for example

/**
 * Create a new PDPage content stream.
 *
 * @param document The document the page is part of.
 * @param sourcePage The page to write the contents to.
 * @param appendContent Indicates whether content will be overwritten, appended or prepended.
 * @param compress Tell if the content stream should compress the page contents.
 * @param resetContext Tell if the graphic context should be reset. This is only relevant when
 * the appendContent parameter is set to {@link AppendMode#APPEND}. You should use this when
 * appending to an existing stream, because the existing stream may have changed graphic
 * properties (e.g. scaling, rotation).
 * @throws IOException If there is an error writing to the page contents.
 */
public PDPageContentStream(PDDocument document, PDPage sourcePage, AppendMode appendContent,
                           boolean compress, boolean resetContext) throws IOException

Therefore

PDPageContentStream contents = new PDPageContentStream(doc, page, AppendMode.APPEND, true, true);

You should make your code work as expected.

Or, if you want an image in the background, try it

PDPageContentStream contents = new PDPageContentStream(doc, page, AppendMode.PREPEND, true, true);

Note, however, that in some cases, the picture is not visible in the background, such as if existing content begins with an instruction to fill the entire page area with white. In this case, the watermark must be applied on top of the existing content in some transparent way.

Related Problems and Solutions