How to add a printable or non-printable bitmap stamp to a PDF?

Tags: annotationsstamp annotationimagesprint flagiText 5

I would like to add a bitmap stamp to a PDF file, that would be either printable or non-printable depending on the actual Acrobat Reader print settings. I.e.

  • when a user selects the option "Document" in Adobe Reader's Print Dialog box, it would not be printed, but
  • when "Document and stamps" is selected, then the bitmap would print

Right now I can create either printable or non-printable bitmap, but I am unable to create a bitmap that would be both printable and non-printable depending on users choice.

Posted on StackOverflow on Nov 19, 2012 by Vojtěch Dohnal

Creating stamp annotations is described in Chapter 7 of iText in Action - Second Edition, more specifically in the TimeTableAnnotations3 example:

PdfAnnotation annotation = PdfAnnotation.createStamp(stamper.getWriter(),
    rect, "Press only", "NotForPublicRelease");
annotation.setFlags(PdfAnnotation.FLAGS_PRINT);

If you look at the print preview, you can see that these annotations don't show up if you print the Document without stamps:

Print preview
Print preview

In C#, the code is very similar to the Java code:

PdfAnnotation annotation = PdfAnnotation.CreateStamp(
    stamper.Writer, rect, "Press only", "NotForPublicRelease"
);
annotation.Flags = PdfAnnotation.FLAGS_PRINT;

Note that a PDF viewer should have predefined icons for at least the following names:

  • Approved,
  • Experimental,
  • NotApproved,
  • AsIs,
  • Expired,
  • NotForPublicRelease,
  • Confidential,
  • Final,
  • Sold,
  • Departmental,
  • ForComment,
  • TopSecret,
  • Draft,
  • ForPublicRelease.

What these icons look like will depend from viewer to viewer.

You want to use an image instead of one of these predefined stamps. This is shown in the AddStamp example. We need to create an appearance for the stamp annotation and add it like this:

public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
    PdfReader reader = new PdfReader(src);
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
    Image img = Image.getInstance(IMG);
    float w = img.getScaledWidth();
    float h = img.getScaledHeight();
    Rectangle location = new Rectangle(36, 770 - h, 36 + w, 770);
    PdfAnnotation stamp = PdfAnnotation.createStamp(
        stamper.getWriter(), location, null, "ITEXT");                     
    img.setAbsolutePosition(0, 0);
    PdfContentByte cb = stamper.getOverContent(1);
    PdfAppearance app = cb.createAppearance(w, h);
    app.addImage(img);
    stamp.setAppearance(PdfName.N, app);
    stamp.setFlags(PdfAnnotation.FLAGS_PRINT);
    stamper.addAnnotation(stamp, 1);
    stamper.close();
    reader.close();
}

Additional answer by the OP: I will add here the working solution, since it was not really straightforward to figure it out from provided examples. Now there is a custom bitmap stamp annotation within the PDF doc and when clicked, the properties window of digital signature appears.

PdfReader reader = new PdfReader(this.inputPDF);
PdfStamper stamper = new PdfStamper(reader, fs);
PdfSignatureAppearance sap;
Rectangle stampRect = null;
//Add stamp annotation
if (StampImagePath != null && StampImagePath.Length > 0 && File.Exists(StampImagePath))
{
    Image stampImg = Image.GetInstance(stampImagePath);
    Rectangle location = new Rectangle(stampXpos, stampYpos, stampXpos + stampImg.Width, stampYpos + stampImg.Height);
    PdfAnnotation pdfStamp = PdfAnnotation.CreateStamp(
        stamper.Writer, location, null, Guid.NewGuid().ToString());                    
    stampImg.SetAbsolutePosition(0, 0);
    PdfAppearance app = stamper.GetOverContent(1).CreateAppearance(stampImg.Width, stampImg.Height);
    app.AddImage(stampImg);
    pdfStamp.SetAppearance(PdfName.N, app);
    pdfStamp.SetPage();
    pdfStamp.Flags = PdfAnnotation.FLAGS_PRINT;
    stamper.AddAnnotation(pdfStamp, 1);
    stampRect = location;
}
....
//After signing the document set visible signature to the annotation rectangle
if (stampRect!=null)
    sap.SetVisibleSignature(stampRect, 1, "SignatureESift");