有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java使用基于iText Core的OpenPdf从pdf页面删除或更新添加的图像图标

我在OpenPdf页面中添加了一个图标作为图像对象,该页面基于iText core。这是我的密码

            // 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();

template of added icon into pdf page

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

知道吗


共 (1) 个答案

  1. # 1 楼答案

    在你的平行OpenPDF issue 464中,你另外发布了:

    Here my progress

    Now I can achieve the XObjects added into pdf file, and I can remove them from pdf page this way:

           // 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();
    

    So the XObjects will remove from the screen, but still there is a problem!!!

    When I remove them and try to add a new one, last deleted object appears and add into the pdf page! REALLY!!! :))

    I think there should be another place that these objects should be removed from.

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

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

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

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

    这就解释了你的观察:

    When I remove them and try to add a new one, last deleted object appears and add into the pdf page! REALLY!!! :))

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

    因此,您可以选择其中一种,而不是仅仅删除图像XObject

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

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

    不过,您可以很容易地将图像资源替换为没有任何内容的表单XObject:

    PdfTemplate pdfTemplate = PdfTemplate.createTemplate(pdfStamper.getWriter(), 1, 1);
    
    // replace Xobjects
    for (PdfName key : xobjects.getKeys()) {
        xobjects.put(key, pdfTemplate.getIndirectReference());
    }
    

    RemoveImage测试testRemoveImageAddedLikeHamidReza


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

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

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