如何使用PDFBox添加背景图片到PDF文件?

3

我正在使用Java PDFBox 2.0版本。我想知道如何将背景图片添加到pdf中。在pdfbox.apache.org上我找不到任何好的例子。

3个回答

1

对于每一页都要执行此操作,即从0到doc.getNumberOfPages():

    PDPage pdPage = doc.getPage(page);
    InputStream oldContentStream = pdPage.getContents();
    byte[] ba = IOUtils.toByteArray(oldContentStream);
    oldContentStream.close();

    // brings a warning because a content stream already exists
    PDPageContentStream newContentStream = new PDPageContentStream(doc, pdPage, false, true);

    // createFromFile is the easiest way with an image file
    // if you already have the image in a BufferedImage, 
    // call LosslessFactory.createFromImage() instead
    PDImageXObject pdImage = PDImageXObject.createFromFile(imagePath, doc);
    newContentStream.saveGraphicsState();
    newContentStream.drawImage(pdImage, 0, 0);
    newContentStream.restoreGraphicsState();
    newContentStream.close();

    // append the saved existing content stream
    PDPageContentStream newContentStream2 = new PDPageContentStream(doc, pdPage, true, true);
    newContentStream2.appendRawCommands(ba); // deprecated... needs to be rediscussed among devs
    newContentStream2.close();           

我认为有另一种更加繁琐的方式来实现,即通过使用getContentStreams()从页面获取PDStream对象的迭代器,构建一个列表,将新的流插入到开头,并使用setContents()将此PDStream列表重新分配给页面。如果需要,我可以将其添加为替代方案。


在我看来,如果还有一个PDPageContentStream构造函数可以将流添加为第一个页面内容流将是非常好的。 - mkl
@mkl 我没有一个好的构造函数API添加的想法。已经有很多构造函数了。 - Tilman Hausherr
我对构造函数API的改进没有好的想法。也许可以使用枚举集合作为构造函数的参数,而不是再加一个布尔值。 - mkl
请创建一个问题 - 参见 PDFBOX-3084 - mkl
1
是的,您可以(而且应该!)在同一文档中重复使用PDImageXObject。但是您仍然需要为每个页面绘制它。 - Tilman Hausherr
显示剩余3条评论

1

这对我来说效果最好...(请注意使用的AppendMode.PREPEND)

    InputStream is = getClass().getResourceAsStream("/yourImageFileNameWithExtenstion");
    PDImageXObject pdImageXObject = PDImageXObject.createFromByteArray(document, is.readAllBytes(), "");
    for (int i = 0; i < document.getNumberOfPages(); i++) {
        PDPage page = document.getPage(i);
        PDPageContentStream cos = new PDPageContentStream(document, page, AppendMode.PREPEND, true);
        cos.drawImage(pdImageXObject, 0, 0, page.getMediaBox().getWidth(), page.getMediaBox().getHeight());
        cos.close();
    }

你为每个页面创建一个新的图像 Xobject。如果你在循环之前创建它一次并在每个页面上重复使用它,那么你的结果 PDF 将会更小。 - mkl
感谢mkl指出。你是正确的 :) - Pioneer

0

调用 PDPageContentStream.drawImage

val document = PDDocument()
val page = PDPage()
document.addPage(page)
val contentStream = PDPageContentStream(document, page)

val imageBytes = this::class.java.getResourceAsStream("/image.jpg").readAllBytes()
val image = PDImageXObject.createFromByteArray(document, imageBytes, "background")
contentStream.drawImage(image, 0f, 0f, page.mediaBox.width, page.mediaBox.height)

contentStream.close()
page.close()

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