简体   繁体   English

PDFBox - 从页面中删除图像并在不同位置添加相同的图像

[英]PDFBox - Delete image from the page and add same image on different position

I am using PDFBox 2.x version and need to reposition the existing image from the page.我使用的是 PDFBox 2.x 版本,需要重新定位页面中的现有图像 For that, I'm removing the image from the page and adding it back again.为此,我从页面中删除图像并重新添加。 But with my current implementation, it is not showing either image.但是在我当前的实现中,它没有显示任何图像。

Please help me with this and let me know where I'm going wrong.请帮我解决这个问题,让我知道我哪里出错了。

try {
  PDDocument document = PDDocument.load(new File("..\\sampleWithImage_with_barcode_img.pdf"));

  PDDocument newDocument = new PDDocument();
  for (int i = 0; i < document.getNumberOfPages(); i++) {
    PDPage sourcePage = document.getPage(i);
    PDPage pdPage = newDocument.importPage(sourcePage);
    pdPage.setResources(sourcePage.getResources());

    //To remove existing from the page
    stripUnusedImages(pdPage, newDocument);

    //ADD OTHER IMAGE
    PDImageXObject pdImage = PDImageXObject.createFromFile("D:\\copy\\pic.jpg", newDocument);

    PDPageContentStream contents = new PDPageContentStream(newDocument, pdPage,
      PDPageContentStream.AppendMode.APPEND, true);

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

    System.out.println("Image inserted Successfully.");

    // Closing the PDPageContentStream object
    contents.close();
  }
  newDocument.save("..\\RemovedImage.pdf");
  document.close();
  newDocument.close();

} catch (Exception e) {
  e.printStackTrace();
}

//Method to remove image
protected void stripUnusedImages(PDPage page, PDDocument document) throws IOException, XmpParsingException {
  PDResources resources = copyResources(page);
  PDFStreamParser parser = new PDFStreamParser(page);
  parser.parse();

  List < Object > tokens = parser.getTokens();
  System.out.println("Total Tokens=" + tokens.size());
  List < Object > newTokens = new ArrayList < Object > ();
  for (int j = 0; j < tokens.size(); j++) {
    Object token = tokens.get(j);
    if (token instanceof COSName) {
      COSName cosname = (COSName) token;
      PDXObject o = resources.getXObject(cosname);
      if (o instanceof PDImageXObject) {
        PDImageXObject pdImageXObject = (PDImageXObject) o;
        if (pdImageXObject.getMetadata() != null) {
          System.out.println("pdImageXObjec metadata exist");
          newTokens.remove(newTokens.size() - 1);
          continue;
        }
      }
    }

    newTokens.add(token);
  }

  PDStream newContents = new PDStream(document);
  OutputStream outputStream = newContents.createOutputStream();
  ContentStreamWriter writer = new ContentStreamWriter(outputStream);
  writer.writeTokens(newTokens);
  outputStream.close();
  newContents.addCompression();
  page.setContents(newContents);
}

The PDPageContentStream is constructed like this: PDPageContentStream的构造如下:

PDPageContentStream contents = new PDPageContentStream(newDocument, pdPage,
  PDPageContentStream.AppendMode.APPEND, true);

Tilman Hausherr in a comment proposed adding a fifth "true" parameter : Tilman Hausherr 在评论中提议添加第五个“true”参数

PDPageContentStream contents = new PDPageContentStream(newDocument, pdPage,
  PDPageContentStream.AppendMode.APPEND, true, true);

This causes the previously existing page content to be enveloped in a save-graphics-state/restore-graphics-state frame which resets the graphics state at the end to the original one to prevent changes in particular to the current transformation matrix from influencing one's new additions.这会导致先前存在的页面内容被封装在保存图形状态/恢复图形状态框架中,该框架将最后的图形状态重置为原始状态,以防止特别是当前转换矩阵的变化影响新的补充。

Ronak additionally according to a comment per his requirement changed AppendMode from APPEND to PREPEND in 3rd param value.此外,Ronak 根据他的要求的评论第三个参数值中的 AppendMode从 APPEND更改为 PREPEND This causes his changes to be added in the background, not the foreground.这会导致他的更改添加到后台,而不是前台。

So the final version of the PDPageContentStream construction is this:所以PDPageContentStream构造的最终版本是这样的:

PDPageContentStream contents = new PDPageContentStream(newDocument, pdPage,
  PDPageContentStream.AppendMode.PREPEND, true, true);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM