I'm using BIRT to generate a simple report with PDF output. This document has some gaps (filled with a placeholder image with an specific color, which is inserted as embedded image in BIRT) that I would like to replace with a user provided image.
BIRT uses iText under the covers, so I decided to go with iText too, in its version 5. The document looks like this:
Now, I have written this code in order to fill only the first gap:
private void replaceStream(PRStream orig, PdfStream stream) throws IOException {
orig.clear();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
stream.writeContent(baos);
orig.setData(baos.toByteArray(), false);
for (PdfName name : stream.getKeys()) {
orig.put(name, stream.get(name));
}
}
private void placeSignature(File source, File target, File signature)
throws IOException, DocumentException {
PdfReader reader = new PdfReader(source.getPath());
PdfObject obj;
for (int i = 1; i <= reader.getXrefSize(); i++) {
obj = reader.getPdfObject(i);
if (obj != null && obj.isStream()) {
PRStream stream = (PRStream) obj;
byte[] b;
try {
b = PdfReader.getStreamBytes(stream);
} catch (UnsupportedPdfException e) {
b = PdfReader.getStreamBytesRaw(stream);
}
BufferedImage img = ImageIO.read(new ByteArrayInputStream(b));
if (img != null) {
boolean signaturePlaceholder = true;
for (int x = 0; x < img.getWidth(); x++) {
for (int y = 0; y < img.getHeight(); y++) {
// Check if image is a placeholder, matches a colour
if (img.getRGB(x, y) != -65) {
signaturePlaceholder = false;
}
}
}
if (signaturePlaceholder) {
Image img2 = Image.getInstance(signature.getPath());
PdfImage newImg = new PdfImage(img2, "", null);
replaceStream(stream, newImg);
System.out.println("Replaced!");
break;
}
}
}
}
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(target));
stamper.close();
reader.close();
}
@Test
public void testReplace() throws IOException, DocumentException {
placeSignature(new File("src/test/resources/signature_test2.pdf"),
new File("target/signature_test2.pdf"),
new File("src/test/resources/signature.jpg"));
}
However, when running the test, that's the result I have:
It seems that the PDF stream gets shared across all the image tags. However, I would like to change only the content for the first. If I use another image to fill any of the gaps (with different size, for example), it doesn't get replaced.
Question is, is there some workaround for this issue when parsing the PDF or do I need to use different images for each of the placeholders while creating the report in BIRT.
This is the link to the sample PDF file.