问题描述
我正在使用PDFBox 2.x版本,需要从页面上重新定位现有图像。为此,我要从页面中删除图像,然后再次添加回去。但是在我当前的实现中,它不会显示任何图像。
请帮助我,让我知道我要去哪里了。
try {
PDDocument document = PDDocument.load(new File("..\\sampleWithImage_with_barcode_img.pdf"));
PDDocument newDocument = new PDDocument();
for (int i = 0; i < document.getNumberOfPages(); i++) {
PDPage sourcePage = document.getPage(i);
PDPage pdPage = newDocument.importPage(sourcePage);
pdPage.setResources(sourcePage.getResources());
//To remove existing from the page
stripUnusedImages(pdPage,newDocument);
//ADD OTHER IMAGE
PDImageXObject pdImage = PDImageXObject.createFromFile("D:\\copy\\pic.jpg",newDocument);
PDPageContentStream contents = new PDPageContentStream(newDocument,pdPage,PDPageContentStream.AppendMode.APPEND,true);
// Drawing the image in the PDF document
contents.drawImage(pdImage,50,30);
System.out.println("Image inserted Successfully.");
// Closing the PDPageContentStream object
contents.close();
}
newDocument.save("..\\RemovedImage.pdf");
document.close();
newDocument.close();
} catch (Exception e) {
e.printstacktrace();
}
//Method to remove image
protected void stripUnusedImages(PDPage page,PDDocument document) throws IOException,XmpParsingException {
PDResources resources = copyResources(page);
PDFStreamParser parser = new PDFStreamParser(page);
parser.parse();
List < Object > tokens = parser.getTokens();
System.out.println("Total Tokens=" + tokens.size());
List < Object > newTokens = new ArrayList < Object > ();
for (int j = 0; j < tokens.size(); j++) {
Object token = tokens.get(j);
if (token instanceof COSName) {
COSName cosname = (COSName) token;
PDXObject o = resources.getXObject(cosname);
if (o instanceof PDImageXObject) {
PDImageXObject pdImageXObject = (PDImageXObject) o;
if (pdImageXObject.getMetadata() != null) {
System.out.println("pdImageXObjec Metadata exist");
newTokens.remove(newTokens.size() - 1);
continue;
}
}
}
newTokens.add(token);
}
PDStream newContents = new PDStream(document);
OutputStream outputStream = newContents.createOutputStream();
ContentStreamWriter writer = new ContentStreamWriter(outputStream);
writer.writetokens(newTokens);
outputStream.close();
newContents.addCompression();
page.setContents(newContents);
}
解决方法
PDPageContentStream
的构造如下:
PDPageContentStream contents = new PDPageContentStream(newDocument,pdPage,PDPageContentStream.AppendMode.APPEND,true);
蒂尔曼·豪瑟(Tilman Hausherr)在评论中建议添加第五个“ true”参数:
PDPageContentStream contents = new PDPageContentStream(newDocument,true,true);
这将导致先前存在的页面内容被封装在save-graphics-state / restore-graphics-state框架中,该框架将最后的图形状态重置为原始状态,以防止特别是对当前转换矩阵的更改。影响一个人的新事物。
Ronak还会根据评论根据他的要求,将第3个参数值中的AppendMode 从APPEND更改为PREPEND 。这会使他的更改添加到后台,而不是前景。
所以PDPageContentStream
结构的最终版本是这样的:
PDPageContentStream contents = new PDPageContentStream(newDocument,PDPageContentStream.AppendMode.PREPEND,true);