首页 > 解决方案 > 删除图像后 PDFBox 错误 - 此页面存在错误。Acrobat 可能无法正确显示页面

问题描述

我正在使用 pdfbox 库 2.0 版本。我必须从页面中删除选定的图像并添加另一个图像。它工作正常。但是当我打开该文件时,它会显示一条警告消息:此页面上存在错误。Acrobat 可能无法正确显示页面。截图如下:

错误图像

特此分享删除图像并添加其他图像的代码:(编辑修复)

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

        for (PDPage page : document.getPages()) {
            PDResources pdResources = page.getResources();
            String[] qrCodeCosName = new String[1];

            pdResources.getXObjectNames().forEach(propertyName -> {
                if (!pdResources.isImageXObject(propertyName)) {
                    return;
                }
                PDXObject o;
                try {
                    o = pdResources.getXObject(propertyName);
                    if (o instanceof PDImageXObject) {
                        PDImageXObject pdImageXObject = (PDImageXObject) o;
                        if (pdImageXObject.getMetadata() != null) {
                            // TO REMOVE FROM RESOURCE
                            ((COSDictionary) pdResources.getCOSObject().getDictionaryObject(COSName.XOBJECT))
                                    .removeItem(propertyName);
                            qrCodeCosName[0] = propertyName.getName();
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });

            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;

                    // find image - remove it
                    if (op.getName().equals("Do")) {
                        COSName cosName = (COSName) tokens.get(j - 1);
                        if (cosName.getName().equals(qrCodeCosName[0])) {
                            newTokens.remove(newTokens.size() - 1);
                            continue;
                        }
                    }
                    newTokens.add(token);
                }

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

                // ADD OTHER IMAGE
                PDImageXObject pdImage = PDImageXObject.createFromFile("D:\\copy\\ind.png", document);

                PDPageContentStream contents = new PDPageContentStream(document, page,
                        PDPageContentStream.AppendMode.PREPEND, true, true);

                contents.saveGraphicsState();
                // Drawing the image in the PDF document
                contents.drawImage(pdImage, 0, 0, 50, 30);
                contents.restoreGraphicsState();

                System.out.println("Image inserted Successfully.");

                // Closing the PDPageContentStream object
                contents.close();

            }

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

请帮我解决这个问题。 此外,期待其他代码审查评论关于正确执行此操作所需的更改。:)

标签: javapdfbox

解决方案


根据@Tilman Hausherr 的建议,下面的代码对我有用:

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

        for (PDPage page : document.getPages()) {
            PDResources pdResources = page.getResources();
            String[] qrCodeCosName = new String[1];

            pdResources.getXObjectNames().forEach(propertyName -> {
                if (!pdResources.isImageXObject(propertyName)) {
                    return;
                }
                PDXObject o;
                try {
                    o = pdResources.getXObject(propertyName);
                    if (o instanceof PDImageXObject) {
                        PDImageXObject pdImageXObject = (PDImageXObject) o;
                        if (pdImageXObject.getMetadata() != null) {
                            // TO REMOVE FROM RESOURCE
                            ((COSDictionary) pdResources.getCOSObject().getDictionaryObject(COSName.XOBJECT))
                                    .removeItem(propertyName);
                            qrCodeCosName[0] = propertyName.getName();
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });

            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;

                    // find image - remove it
                    if (op.getName().equals("Do")) {
                        COSName cosName = (COSName) tokens.get(j - 1);
                        if (cosName.getName().equals(qrCodeCosName[0])) {
                            newTokens.remove(newTokens.size() - 1);
                            continue;
                        }
                    }
                    newTokens.add(token);
                }

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

                // ADD OTHER IMAGE
                PDImageXObject pdImage = PDImageXObject.createFromFile("D:\\copy\\ind.png", document);

                PDPageContentStream contents = new PDPageContentStream(document, page,
                        PDPageContentStream.AppendMode.PREPEND, true, true);

                contents.saveGraphicsState();
                // Drawing the image in the PDF document
                contents.drawImage(pdImage, 0, 0, 50, 30);
                contents.restoreGraphicsState();

                System.out.println("Image inserted Successfully.");

                // Closing the PDPageContentStream object
                contents.close();

            }

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

推荐阅读