使用PDFbox从PDF文件中删除图像 如果您致电remove ... 如果您直接致电removeImages ...

问题描述

我正在尝试使用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 ...

remove中您

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

因此,在最后一步中,您覆盖您可能在removeImages 中所做的所有更改,最后将原始文件保存在“ RemoveImage.pdf”中!

如果您直接致电removeImages ...

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

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

    page.getCOSObject().removeItem(propertyName);
    

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

  • 您从页面内容中删除了 all Do 指令,不仅是图像Xobject的指令,因此您可能会删除多余的指令。