Adding watermark to PDF using iText7 C#

3.7k views Asked by At

I am using iText 7 for C#, or actually I am migrating from iTextSharp 5 to iText 7. In iTextSharp, I have used IPdfPageEvent (more specifically the PdfPageEventHelper helper class) to add a watermark to PDF:

public MyPageEvent extends PdfPageEventHelper {
  private Image waterMark;
  public MyPageEvent(Image img) {
    waterMark = img;
  }
  public void OnEndPage(PdfWriter writer, Document doc) {
    PdfContentByte content = writer.GetUnderContent();
    content.AddImage(waterMark);
  }
}

Image watermarkImage = new Image(imgPath);
watermarkImage.setAbsolutePosition(x, y);
writer.setPageEvent( new MyPageEvent(watermarkImage) );

Now that i am looking for iText 7 equivalent for that. I can't find the IPageEvent interface, nor classes such as PdfPageEventHelper in iText 7 for C#.

1

There are 1 answers

0
Bruno Lowagie On

Please take a look at Chapter 7: Handling events; setting viewer preferences and writer properties where the event system is explained.

In this chapter, we explain how to use the addEventHandler() method for the following events:

  • START_PAGE– triggered when a new page is started,
  • END_PAGE– triggered right before a new page is started,
  • INSERT_PAGE– triggered when a page is inserted, and
  • REMOVE_PAGE– triggered when a page is removed.

In iText 5, it was necessary to add a watermark in the OnEndPage() method. In iText 7, you can choose for the START_PAGE or END_PAGE event.

Suppose that you want to add an image as a watermark. In that case, you'd create an implementation of the IEventHandler interface like this:

protected class TransparentImage implements IEventHandler {
    protected PdfExtGState gState;
    protected Image img;
    public TransparentImage(Image img) {
        this.img = img;
        gState = new PdfExtGState().setFillOpacity(0.2f);
    }
    @Override
    public void handleEvent(Event event) {
        PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
        PdfDocument pdf = docEvent.getDocument();
        PdfPage page = docEvent.getPage();
        Rectangle pageSize = page.getPageSize();
        PdfCanvas pdfCanvas = new PdfCanvas(
            page.getLastContentStream(), page.getResources(), pdf);
        pdfCanvas.saveState().setExtGState(gState);
        Canvas canvas = new Canvas(pdfCanvas, pdf, page.getPageSize());
        canvas.add(img
            .scaleAbsolute(pageSize.getWidth(), pageSize.getHeight()));
        pdfCanvas.restoreState();
        pdfCanvas.release();
    }
}

There's also an example where we add text instead of an image. More specifically the a header:

protected class Header implements IEventHandler {
    String header;
    public Header(String header) {
        this.header = header;
    }
    @Override
    public void handleEvent(Event event) {
        PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
        PdfDocument pdf = docEvent.getDocument();
        PdfPage page = docEvent.getPage();
        if (pdf.getPageNumber(page) == 1) return;
        Rectangle pageSize = page.getPageSize();
        PdfCanvas pdfCanvas = new PdfCanvas(
            page.getLastContentStream(), page.getResources(), pdf);
        Canvas canvas = new Canvas(pdfCanvas, pdf, pageSize);
        canvas.showTextAligned(header,
            pageSize.getWidth() / 2,
            pageSize.getTop() - 30, TextAlignment.CENTER);
    }
}

Using such an IEventHandler implementation is easy:

PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
pdf.addEventHandler(PdfDocumentEvent.START_PAGE,
    new Header("The Strange Case of Dr. Jekyll and Mr. Hyde"));

As you can see, you can simply add the event handler to the PdfDocument specifying for which event the handler has to be triggered.

Important: the code I shared is Java code, but the same classes, interfaces and methods exist in C#, so it shouldn't be a problem for you to adapt my examples.