java - 使用 PDFbox 从 PDF 文件中删除图像

标签 java pdf pdfbox

我正在尝试使用 java 和 PDFbox 从 PDF 中删除图像。图像不是内联的,并且 PDF 没有图案或表格。 pdf 文件包含 2 张图像。 PDFdebugger 工具显示资源 >>​​ XObject >> IM3 和 IM5。问题是:我显示输出的 pdf 文件,但图像没有被删除。

public class DeleteImage {
    public static void removeImages(String pdfFile) throws Exception {
        PDDocument document = PDDocument.load(new File(pdfFile));

        for (PDPage page : document.getPages()) {
            PDResources pdResources = page.getResources();
            pdResources.getXObjectNames().forEach(propertyName -> {
                if(!pdResources.isImageXObject(propertyName)) {
                    return;
                }
                PDXObject o;
                try {
                    o = pdResources.getXObject(propertyName);
                    if (o instanceof PDImageXObject) {
                        System.out.println("propertyName" + propertyName);
                        page.getCOSObject().removeItem(propertyName);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });

            for (COSName name :  page.getResources().getPatternNames()) {
                PDAbstractPattern pattern = page.getResources().getPattern(name);
                System.out.println("have pattern");
            }
              
            PDFStreamParser parser = new PDFStreamParser(page);
            parser.parse();
            List<Object> tokens = parser.getTokens();
            System.out.println("original tokens size" + tokens.size());
            List<Object> newTokens = new ArrayList<Object>();

            for(int j=0; j<tokens.size(); j++) {
                Object token = tokens.get( j );
                if( token instanceof Operator ) {
                    Operator op = (Operator)token;

                    System.out.println("operation" + op.getName());
                    //find image - remove it
                    if( op.getName().equals("Do") ) {
                        System.out.println("op equals Do");
                        newTokens.remove(newTokens.size()-1);
                        continue;
                    } else if ("BI".equals(op.getName())) {
                        System.out.println("inline -- op equals BI");
                    } else {
                        System.out.println("op not quals Do");
                    }
                }
                newTokens.add(token);
            }

            PDDocument newDoc = new PDDocument();
            PDPage newPage = newDoc.importPage(page);
            newPage.setResources(page.getResources());

            System.out.println("tokens size" + newTokens.size());
            PDStream newContents = new PDStream(newDoc);
            OutputStream out = newContents.createOutputStream();
            ContentStreamWriter writer = new ContentStreamWriter( out );
            writer.writeTokens( newTokens);
            out.close();
            newPage.setContents( newContents );
        }

        document.save("RemoveImage.pdf");
        document.close();
    }

    public static void remove(String pdfFile) throws Exception {
        PDDocument document = PDDocument.load(new File(pdfFile));
        PDResources resources = null;
        
        for (PDPage page : document.getPages()) {
            resources = page.getResources();

            for (COSName name : resources.getXObjectNames()) {
                PDXObject xobject = resources.getXObject(name);
                
                if (xobject instanceof PDImageXObject) {
                    System.out.println("have image");
                    removeImages(pdfFile);
                }
            }
        }
        document.save("RemoveImage.pdf");
        document.close();
    }
}

最佳答案

如果您调用remove...

删除中你

  • 将 PDF 加载到文档中,
  • 遍历文档的页面,并针对每个页面
    • 迭代 XObject 资源,并针对每个 Xobject
      • 检查是否是图像Xobject,如果是
        • 调用removeImages加载相同的原始文件,对其进行处理,并将结果保存为“RemoveImage.pdf”。
  • 完成所有处理后,将未更改的文档保存到“RemoveImage.pdf”。

因此,在最后一步中,您覆盖您在 removeImages 中所做的任何更改,并最终得到“RemoveImage.pdf”中的原始文件!

如果您直接调用removeImages...

removeImages中,您做了一些更改,但存在某些问题:

  • 每当您找到图像 Xobject 资源时,您都会尝试直接将其从页面中删除

    page.getCOSObject().removeItem(propertyName);
    

    但是图像 Xobject 资源不是 page 的直接子级,它由 pdResources 管理,因此您应该从那里删除它。

  • 您从页面内容中删除了所有 Do 指令,而不仅仅是图像 Xobject 的指令,因此您删除的内容可能比您想要的多。

关于java - 使用 PDFbox 从 PDF 文件中删除图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63598888/

相关文章:

java - 忽略 jackson 属性(property)

java - 无法在 PDBox PDF 文档中插入制表符和空格

java - 确定 PDF 页面是包含文本还是纯图片

java - 如何使任何 pdf 文件中的水印文本不可选择?

java - 某些客户端未设置 Cookie

java - 在 Java 中将 Crystal 报表导出为 PDF

java - JSP 查询减表值

php - 从 html 超链接到 pdf 内的书签

java - Itext 中的 Bouncy CasSTLe 错误

html - 图像不使用 jsPDF 在 PDF 上呈现?