1

我已经使用基于 iText 核心的OpenPdfPDF在页面中添加了一个图标作为图像对象。这是我的代码

            // inout stream from file
            InputStream inputStream = new FileInputStream(file);

            // we create a reader for a certain document
            PdfReader reader = new PdfReader(inputStream);

            // we create a stamper that will copy the document to a new file
            PdfStamper stamp = new PdfStamper(reader, new FileOutputStream(file));

            // adding content to each page
            PdfContentByte over;

            // get watermark icon
            Image img = Image.getInstance(PublicFunction.getByteFromDrawable(context, R.drawable.ic_chat_lawone_new));
            img.setAnnotation(new Annotation(0, 0, 0, 0, "https://github.com/LibrePDF/OpenPDF"));
            img.setAbsolutePosition(pointF.x, pointF.y);
            img.scaleAbsolute(50, 50);

            // get page file number count
            int pageNumbers = reader.getNumberOfPages();

            if (pageNumbers < pageIndex) {
                // closing PdfStamper will generate the new PDF file
                stamp.close();
                throw new PDFException("page index is out of pdf file page numbers", new Throwable());
            }

            // annotation added into target page
            over = stamp.getOverContent(pageIndex);
            if (over == null) {
                stamp.close();
                throw new PDFException("getUnderContent is null", new Throwable());
            }

            over.addImage(img);

            // closing PdfStamper will generate the new PDF file
            stamp.close();

            // close reader
            reader.close();

将图标添加到 pdf 页面的模板

现在我需要在用户点击时删除或更新添加的图像对象的颜色,我有返回的点击功能MotionEvent,现在我需要删除或更新或替换添加的图像对象。

任何想法?!

4

1 回答 1

0

在您的并行OpenPDF 问题 464中,您还发布了:

这是我的进步

现在我可以实现将XObjects添加到 pdf 文件中,并且可以通过以下方式将它们从 pdf 页面中删除:

       // inout stream from file
       InputStream inputStream = new FileInputStream(file);

       // we create a reader for a certain document
       PdfReader pdfReader = new PdfReader(inputStream);

       // get page file number count
       int pageNumbers = pdfReader.getNumberOfPages();

       // we create a stamper that will copy the document to a new file

       PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileOutputStream(file));

       // get page
       PdfDictionary page = pdfReader.getPageN(currPage);
       PdfDictionary resources = page.getAsDict(PdfName.RESOURCES);

       // get page resources
       PdfArray annots = resources.getAsArray(PdfName.ANNOTS);
       PdfDictionary xobjects = resources.getAsDict(PdfName.XOBJECT);

      // remove Xobjects
      for (PdfName key : xobjects.getKeys()) {
               xobjects.remove(key);
      }

      // remove annots
      for (PdfObject element : annots.getElements()) {
               annots.remove(0);
      }

      // close pdf stamper
      pdfStamper.close();

     // close pdf reader
     pdfReader.close();

所以 XObjects 将从屏幕上移除,但还是有问题!!!

当我删除它们并尝试添加一个新对象时,最后一个删除的对象会出现并添加到 pdf 页面中!真的!!!:))

我认为应该有另一个地方应该删除这些对象。

这里发生的是您确实确实从页面中删除了位图图像资源:

      for (PdfName key : xobjects.getKeys()) {
               xobjects.remove(key);
      }

但您不会删除从内容流中提取这些资源的说明。这有两个后果:

  1. 严格来说,您的 PDF 变得无效,因为从页面资源中未定义的内容流中引用了资源。根据有问题的查看器,这可能会导致警告消息。
  2. 如果 PDF 被进一步处理并且一些新的 XObject 被添加到具有相同资源名称的同一页面中,则原来的图像绘制指令现在再次具有要绘制的资源并使其再次出现在原来的位置。

这解释了你的观察:

当我删除它们并尝试添加一个新对象时,最后一个删除的对象会出现并添加到 pdf 页面中!真的!!!:))

我假设您在测试中使用了相同的源图像,所以看起来原始图像再次出现在原始位置,而实际上新图像出现在那里。

因此,您不仅可以删除图像 XObject,还可以选择

  • 还从内容流中删除 XObject 绘图指令或
  • 将图像 XObject 替换为不可见的 XObject。

前一个选项通常很重要,特别是如果您的 PDF 工具还允许对页面内容进行其他更改。对于 iText 5 或 iText 7,我建议使用PdfContentStreamEditor(参见此处)/ PdfCanvasEditor(参见此处)类从页面内容流中查找和删除Do操作,但我还没有该类的 OpenPDF 版本。

但是,您可以很容易地用没有任何内容的 XObjects 形式替换图像资源:

PdfTemplate pdfTemplate = PdfTemplate.createTemplate(pdfStamper.getWriter(), 1, 1);

// replace Xobjects
for (PdfName key : xobjects.getKeys()) {
    xobjects.put(key, pdfTemplate.getIndirectReference());
}

RemoveImage测试testRemoveImageAddedLikeHamidReza


请注意, 用空 XObjects 替换所有 XObjects有一个明显的缺点,它会替换所有XObjects,而不仅仅是您的工具之前创建的那些!因此,如果您的工具处理的原始 PDF 还在其直接内容流中绘制了 XObject,则这些 XObject 也将呈现为不可见。如果您不希望这样,您需要一些特定的标准来识别您添加的图像 XObject 并仅替换它们。

此外,还有其他问题正在发生:每次处理OverContenta 中的页面时PdfStamper,该页面的预先存在的内容都会被包装到q / Q(保存图形状态/恢复图形状态)信封中,以防止先前内容中图形状态的变化会渗透并混淆您的OverContent添加。因此,如果您在工具中多次操作文件,则原始页面内容可能会包裹在此类信封的相当深的嵌套中。不幸的是,PDF 阅读器可能只支持有限的嵌套深度,例如 ISO 32000-1 提到最大深度为 28 个信封。

因此,如果您仍然有机会彻底检查您的设计,您应该考虑将图像放入注释外观而不是页面内容中。毕竟,您已经生成了注释,目前只是为了传输链接,因此您也可以生成带有外观的注释。

于 2021-01-10T18:11:35.053 回答