C# – Using iTextSharp PdfStamper to overlay an image on existing PDF

citextsharp

I am able to overlay an image onto an existing PDF document using the PDFStamper and the PdfContentByte content.AddImage method.

My problem comes up when the existing document already has an image overlayed on top. You can actually see the top edge of the small image I am trying to overlay. It is clearly hidden beneath the existing image overlay.

I am having issues trying to get my overlayed image to show up on top of the existing image overlay.

My code:

System.Drawing.Image bitmap

PdfReader pdfReader = new PdfReader(pathToOriginalPdf);
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(pathToTimestampedPdf, FileMode.Create, FileAccess.Write, FileShare.None));

MemoryStream imageStream = new MemoryStream();
bitmap.Save(imageStream, ImageFormat.Bmp);
byte[] bitmapBytes = imageStream.ToArray();

iTextSharp.text.Image image = Image.GetInstance(bitmapBytes);

PdfContentByte underContent;

try
{
    underContent = pdfStamper.GetOverContent(1);
    underContent.AddImage(image);
}

I need a way to either flatten the existing image overlay onto the PDF content or set the z-order such that my newly added overlay can sit on top.

For some reason the PdfStamper is choosing to place the new image below the existing one.

Thanks in advance.

Best Answer

It would help if we could see the PDF in question. Then we wouldn't have to guess, we would know.

None the less, I suspect your "existing image overlay" is part of an annotation. Nothing you put into page contents will ever appear above an annotation.

Options (if I'm right):

Add your own annotation

For this, I'd use a PushbuttonField with LAYOUT_ICON_ONLY. Draw your image into a PdfTemplate, and use that for the button's "icon".

Z-order for annotations is determined by the order of the page's annotation array. New annotations are appended to this array. No problem.

PushbuttonField fld = new PushbuttonField(stamper.getWriter(), box, name);
fld.setLayout(PushbuttonField.LAYOUT_ICON_ONLY);
fld.setImage(myImage);

stamper.addAnnotation(fld.getField(), 1);

You might need to mess around with setScaleIcon(), setHorizontalAdjustment(), setVerticalAdjustment(), setProportionalIcon(), and maybe a couple others to get your image to look exactly how you want it.

Flatten in one pass, add your image in another

If the existing image annotation is something iText can flatten (maybe, maybe not), you can do what you want in two passes. The first pass would simply "setFormFlattening(true);close();", while the second would be everything you're doing now.

ByteArrayOutputStream output = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper( firstReader, output );
stamper.setFormFlattening(true);
stamper.setFreeTextFlatten(true);  // probably not needed.
stamper.close();

PdfReader secondReader = new PdfReader(output.toByteArray());
FileOutputStream finalOutput = new FileOutputStream( outputPath );
stamper = new PdfStamper(secondReader, finalOutput);
// do your thing here.
stamper.getOverContent(1).addImage(image);
Related Topic