我正在尝试使用 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”。
- 调用
- 检查是否是图像Xobject,如果是
- 迭代 XObject 资源,并针对每个 Xobject
- 完成所有处理后,将未更改的
文档
保存到“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/