Löschen Sie ein Bild aus einer PDF-Datei mit PDFbox

Aug 26 2020

Ich versuche, Bilder mit Java und PDFbox aus einem PDF zu löschen. Die Bilder sind nicht inline und das PDF enthält keine Muster oder Formulare. Die PDF-Datei enthält 2 Bilder. Das PDFdebugger-Tool zeigt Ressourcen >> XObject >> IM3 und IM5 an. Das Problem ist: Ich zeige die Ausgabe-PDF-Datei an und die Bilder werden nicht gelöscht.

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

Antworten

1 mkl Aug 26 2020 at 16:04

Wenn Sie anrufen remove...

In removedir

  • Laden Sie das PDF in document,
  • Durchlaufen Sie die Seiten von documentund für jede Seite
    • Durchlaufen Sie die XObject-Ressourcen und jedes Xobject
      • Überprüfen Sie, ob es sich um ein Image-Xobject handelt und ob dies der Fall ist
        • Aufruf removeImages, der dieselbe Originaldatei lädt, verarbeitet und das Ergebnis als "RemoveImage.pdf" speichert.
  • Nach all dieser Verarbeitung speichern Sie die unverändert documentin "RemoveImage.pdf".

In diesem letzten Schritt überschreibenremoveImages Sie alle Änderungen, die Sie möglicherweise vorgenommen haben, und erhalten Ihre Originaldatei in "RemoveImage.pdf"!

Wenn Sie removeImagesdirekt anrufen ...

In removeImagesSie haben einige Änderungen , aber es gibt bestimmte Themen:

  • Wenn Sie eine Bild-Xobject-Ressource finden, versuchen Sie, diese direkt von der Seite zu entfernen

    page.getCOSObject().removeItem(propertyName);
    

    Die Image-Xobject-Ressource ist jedoch kein direktes untergeordnetes Element von page, sondern wird von verwaltet. pdResourcesSie sollten sie daher von dort entfernen.

  • Sie entfernen alle Do- Anweisungen aus dem Seiteninhalt, nicht nur die für Image-Xobjects, sodass Sie wahrscheinlich mehr entfernen, als Sie wollten.