drunkenfist drunkenfist - 1 month ago 12
Java Question

Moving from PDFBox 1.x to PDFBox 2

I have been using PDFBox 1.8 to work with pdfs. Now I'm planning to move to PDFBox 2.0-RC-2. I'm having some trouble in migrating.

With PDFBox 1.8, I used to get tokens from a PDPage using:

PDStream contents = page.getContents();
PDFStreamParser parser = new PDFStreamParser(contents.getStream());
parser.parse();
List<Object> tokens = parser.getTokens();


However,
page.getContents()
returns an InputStream in PDFBox 2. How do I get PDStream? Should I use
page.getContentStreams()
(which returns Iterable) and iterate through it? Also, the constructor
new PDFStreamParser(COSStream)
seems to be deprecated.

The other issue I have is with image replacement. I was replacing one image with another using
replaceWithStream


PDResources resources = page.getResources();
Iterable<COSName> xObjectNames = resources.getXObjectNames();
if (null != xObjectNames) {
for(COSName xObjectName : xObjectNames){
PDXObject object = resources.getXObject(xObjectName);
if (object instanceof PDImageXObject) {
PDImageXObject img1 = (PDImageXObject) object;
PDImageXObject img2 = ....
img1.getCOSStream().replaceWithStream(
img2.getCOSStream());
}
}
}


The
replaceWithStream
method was deprecated in PDFBox 1.8, so in PDFBox 2.0, it has been removed completely. What is the other way to replace img1 with img2?

Answer

Answer to the first part of the question:

PDFStreamParser parser = new PDFStreamParser(page);
parser.parse();
List<Object> pageTokens = parser.getTokens();

Answer to the second part of the question:

What should work if both images have the same filters, size etc is this:

OutputStream os = img1.getCOSStream().createRawOutputStream();
InputStream is = img2.getCOSStream().createRawInputStream();
IOUtils.copy(is, os);
is.close();
os.close();

Update: If they are not identical, also do this:

COSStream c1 = img1.getCOSStream();
COSStream c2 = img2.getCOSStream();
for (COSName name : c1.keySet())
{
    c1.setItem(name, null);
}
for (COSName name : c2.keySet())
{
    c1.setItem(name, c2.getItem(name));
}                
Comments