问题描述
我正在尝试使用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”。
- 调用
- 检查是否为图像Xobject,是否为
- 遍历XObject资源,并针对每个Xobject
- 完成所有处理后,将未更改的
document
保存到“ RemoveImage.pdf”。
因此,在最后一步中,您覆盖您可能在removeImages
中所做的所有更改,最后将原始文件保存在“ RemoveImage.pdf”中!
如果您直接致电removeImages
...
在removeImages
中,您进行了一些更改,但是存在某些问题:
-
每当找到图像Xobject资源时,便会尝试将其直接从页面中删除
page.getCOSObject().removeItem(propertyName);
但是图像Xobject资源不是
page
的直接子资源,它是由pdResources
管理的,因此应该从那里删除它。 -
您从页面内容中删除了 all Do 指令,不仅是图像Xobject的指令,因此您可能会删除多余的指令。