使用Apache PDFBox添加图像到PDF时出现空白页面的问题

3
我正在使用这段代码:https://www.tutorialspoint.com/pdfbox/pdfbox_inserting_image.htm,帮助我向现有的PDF文件中添加图片。问题在于它创建的文件是只有图片的空白页面。
以下是我的代码:
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();
    }

据我所知,我的做法应该是有效的,而且没有任何错误提示,那问题出在哪里呢?

可能是 https://dev59.com/T4bca4cB1Zd3GeqPbNqI 的重复问题。请先尝试该链接,如果不行,请提供您的PDF链接。 - Tilman Hausherr
1
@TilmanHausherr 不是重复问题,但是与之密切相关。这里的问题是由于使用了new PDPageContentStream(doc,page)而导致失败,解决方法是使用至少具有第三个(append)参数的构造函数。您链接的问题中的问题是由于使用了new PDPageContentStream(doc,page,true,true)而导致失败,解决方法是使用具有第五个(resetContext)参数的构造函数。可以考虑为所有关于使用哪个PDPageContentStream构造函数的问题创建一个规范答案。 - mkl
1个回答

3
请您也查看一下您所使用的库的JavaDocs和源代码。您将创建一个PDPageContentStream
PDPageContentStream contents = new PDPageContentStream(doc, 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

因此,您需要使用一个不同的构造函数来保留当前页面内容, 例如:
/**
 * 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

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

您需要让代码按照预期工作。

或者,如果您想要将图像设置为背景,请尝试

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

请注意,在某些情况下,背景中的图像可能不可见,例如,如果现有内容以白色填充整个页面区域的指令开头。在这种情况下,必须在现有内容的顶部应用具有某种透明度的水印。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接