【问题标题】:How to exactly position an Image inside an existing PDF page using PDFBox?如何使用 PDFBox 在现有 PDF 页面内准确定位图像?
【发布时间】:2012-02-17 10:05:04
【问题描述】:

我可以在现有的 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();
}

我想要第一页的图片。

【问题讨论】:

    标签: pdfbox


    【解决方案1】:

    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 sources

    【讨论】:

    • PDPageContentStream(PDDocument document, PDPage sourcePage, boolean appendContent, boolean compress)2.0.0 上已弃用
    • 因为方法 PDPageContentStream(PDDocument document, PDPage sourcePage, boolean appendContent, boolean compress) 已弃用,追加内容的新方法是:PDPageContentStream contentStream = new PDPageContentStream(doc, page, APPEND, true);跨度>
    【解决方案2】:

    试试这个

    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 循环。 这对我很有效!

    【讨论】:

      【解决方案3】:

      我正在创建一个新的 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();
      

      【讨论】:

      • 一般来说,如果答案包括对代码的用途的解释,以及为什么在不介绍其他人的情况下解决问题的原因,答案会更有帮助。感谢您提高答案的参考价值并使其更易于理解!
      【解决方案4】:

      这么晚的答案,但这是为谁在 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()
      

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-04-16
          • 2017-05-10
          • 1970-01-01
          • 2013-07-15
          • 2015-02-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多