如何使用 PDFBox 在现有 PDF 页面中精确定位图像?

发布于 2025-01-06 07:58:06 字数 426 浏览 0 评论 0原文

我可以在现有的 pdf 文档中插入图像,但问题是,

  1. 图像放置在页面底部
  2. 页面变成白色,上面显示新添加的文本。

我正在使用以下代码。

List<PDPage> pages = pdDoc.getDocumentCatalog().getAllPages();

if(pages.size() > 0){
    PDJpeg img = new PDJpeg(pdDoc, in);
    PDPageContentStream stream = new PDPageContentStream(pdDoc,pages.get(0));
    stream.drawImage(img, 60, 60);
    stream.close();
}

我想要第一页上的图像。

I am able to insert an Image inside an existing pdf document, but the problem is,

  1. The image is placed at the bottom of the page
  2. The page becomes white with the newly added text showing on it.

I am using following code.

List<PDPage> pages = pdDoc.getDocumentCatalog().getAllPages();

if(pages.size() > 0){
    PDJpeg img = new PDJpeg(pdDoc, in);
    PDPageContentStream stream = new PDPageContentStream(pdDoc,pages.get(0));
    stream.drawImage(img, 60, 60);
    stream.close();
}

I want the image on the first page.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

萌吟 2025-01-13 07:58:06

PDFBox 是一个处理 PDF 文件的低级库。您负责更多高级功能。因此,在此示例中,您将图像放置在从文档左下角开始的 (60, 60) 处。这就是 stream.drawImage(img, 60, 60); 的作用。

如果您想将图像移动到其他位置,则必须计算并提供所需的位置(可能通过使用 page.findCropBox() 获得的尺寸,或手动输入您的位置)。

至于文本,PDF文档元素是绝对定位的。没有用于重排文本、浮动或类似功能的低级功能。如果您将文本写在图像上,它写在您的图像上。

最后,为了使您的页面变白——您正在创建一个新的内容流,从而覆盖页面的原始内容流。您应该附加到已经可用的流。

相关行是:

PDPageContentStream stream = new PDPageContentStream( pdDoc, pages.get(0));

您应该这样做:

PDPageContentStream stream = new PDPageContentStream( pdDoc, pages.get(0), true, true);

第一个 true 是是否附加内容,最后一个 true (这里并不重要)是是否压缩流。

看一下 AddImageToPDF 示例可从 PDFBox 源获取。

PDFBox is a low-level library to work with PDF files. You are responsible for more high-level features. So in this example, you are placing your image at (60, 60) starting from lower-left corner of your document. That is what stream.drawImage(img, 60, 60); does.

If you want to move your image somewhere else, you have to calculate and provide the wanted location (perhaps from dimensions obtained with page.findCropBox(), or manually input your location).

As for the text, PDF document elements are absolutely positioned. There are no low-level capabilities for re-flowing text, floating or something similar. If you write your text on top of your image, it will be written on top of your image.

Finally, for your page becoming white -- you are creating a new content stream and so overwriting the original one for your page. You should be appending to the already available stream.

The relevant line is:

PDPageContentStream stream = new PDPageContentStream( pdDoc, pages.get(0));

What you should do is call it like this:

PDPageContentStream stream = new PDPageContentStream( pdDoc, pages.get(0), true, true);

The first true is whether to append content, and the final true (not critical here) is whether to compress the stream.

Take a look at AddImageToPDF sample available from PDFBox sources.

始于初秋 2025-01-13 07:58:06

试试这个

doc = PDDocument.load( inputFileName );
PDXObjectImage ximage = null;
ximage = new PDJpeg(doc, new FileInputStream( image )
PDPage page = (PDPage)doc.getDocumentCatalog().getAllPages().get(0);
PDPageContentStream contentStream = new PDPageContentStream(doc, page, true, true);
contentStream.drawImage( ximage, 425, 675 );
contentStream.close();

这将打印第一页中的图像。如果你想打印所有页面,只需放置一个 for 循环,以页数为限制条件。
这对我来说效果很好!

Try this

doc = PDDocument.load( inputFileName );
PDXObjectImage ximage = null;
ximage = new PDJpeg(doc, new FileInputStream( image )
PDPage page = (PDPage)doc.getDocumentCatalog().getAllPages().get(0);
PDPageContentStream contentStream = new PDPageContentStream(doc, page, true, true);
contentStream.drawImage( ximage, 425, 675 );
contentStream.close();

This prints the image in first page. If u want to print in all pages just put on a for loop with a condition of number of pages as the limit.
This worked for me well!

郁金香雨 2025-01-13 07:58:06

答案已经很晚了,但这是为 2020 年使用 Kotlin 进行工作的人准备的:drawImage() 在其内部获取浮点值,所以试试这个:

val file = File(getPdfFile(FILE_NAME))
val document = PDDocument.load(file)
val page = document.getPage(0)
val contentStream: PDPageContentStream
contentStream = PDPageContentStream(document, page, true, true)

// Define a content stream for adding to the PDF
val bitmap: Bitmap? =        ImageSaver(this).setFileName("sign.png").setDirectoryName("signature").load()

val mediaBox: PDRectangle = page.mediaBox
val ximage: PDImageXObject = JPEGFactory.createFromImage(document, bitmap)
           
contentStream.drawImage(ximage, mediaBox.width - 4 * 65, 26f)

// Make sure that the content stream is closed:
contentStream.close()

// Save the final pdf document to a file
pdfSaveLocation = "$directoryPDF/$UPDATED_FILE_NAME"
val pathSave = pdfSaveLocation
document.save(pathSave)
document.close()

So late answer but this is for who works on it in 2020 with Kotlin: drawImage() is getting float values inside itself so try this:

val file = File(getPdfFile(FILE_NAME))
val document = PDDocument.load(file)
val page = document.getPage(0)
val contentStream: PDPageContentStream
contentStream = PDPageContentStream(document, page, true, true)

// Define a content stream for adding to the PDF
val bitmap: Bitmap? =        ImageSaver(this).setFileName("sign.png").setDirectoryName("signature").load()

val mediaBox: PDRectangle = page.mediaBox
val ximage: PDImageXObject = JPEGFactory.createFromImage(document, bitmap)
           
contentStream.drawImage(ximage, mediaBox.width - 4 * 65, 26f)

// Make sure that the content stream is closed:
contentStream.close()

// Save the final pdf document to a file
pdfSaveLocation = "$directoryPDF/$UPDATED_FILE_NAME"
val pathSave = pdfSaveLocation
document.save(pathSave)
document.close()
递刀给你 2025-01-13 07:58:06

我正在创建一个新的 PDF 并循环运行下面的代码 - 每页添加一个图像,下面的坐标以及高度和宽度值对我来说效果很好。

其中 out 是 BufferedImage 引用变量

    PDPage page = new PDPage();
    outputdocument.addPage(page);
    PDPageContentStream contentStream = new PDPageContentStream(outputdocument, page, AppendMode.APPEND, true);
    PDImageXObject pdImageXObject = JPEGFactory.createFromImage(outputdocument, out);
    contentStream.drawImage(pdImageXObject, 5, 2, 600, 750);
    contentStream.close();

I am creating a new PDF and running below code in a loop - to add one image per page and below co-ordinates and height and width values work well for me.

where out is BufferedImage reference variable

    PDPage page = new PDPage();
    outputdocument.addPage(page);
    PDPageContentStream contentStream = new PDPageContentStream(outputdocument, page, AppendMode.APPEND, true);
    PDImageXObject pdImageXObject = JPEGFactory.createFromImage(outputdocument, out);
    contentStream.drawImage(pdImageXObject, 5, 2, 600, 750);
    contentStream.close();
好菇凉咱不稀罕他 2025-01-13 07:58:06

链接为您提供有关 PrintImageLocations 类的详细信息。
此 PrintImageLocations 将为您提供图像的 x 和 y 坐标。

用法:java org.apache.pdfbox.examples.util.PrintImageLocations input-pdf

This link gives you details about Class PrintImageLocations.
This PrintImageLocations will give you the x and y coordinates of the images.

Usage: java org.apache.pdfbox.examples.util.PrintImageLocations input-pdf

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文