0

How do I add a watermark (text or image) in an existing pdf in c#?

I want the watermark displayed for all pages of the pdf.

I tried with itextsharp but the watermark is displaying in only last page of the pdf.

    public void CreateTemplate(string watermarkText, string targetFileName)
    {
        var document = new Document();
        var pdfWriter = PdfWriter.GetInstance(document, new FileStream(targetFileName, FileMode.Create));
        var font = new iTextSharp.text.Font(iTextSharp.text.Font.HELVETICA, 60, iTextSharp.text.Font.NORMAL, iTextSharp.text.Color.LIGHT_GRAY);
        document.Open();
        ColumnText.ShowTextAligned(pdfWriter.DirectContent, Element.ALIGN_CENTER, new Phrase(watermarkText, font), 300, 400, 45);
        document.Close();
    }
    public void AddTextWatermark(string sourceFilePath, string watermarkTemplatePath, string targetFilePath)
    {
        var pdfReaderSource = new PdfReader(sourceFilePath);
        var pdfStamper = new PdfStamper(pdfReaderSource, new FileStream(targetFilePath, FileMode.Create));
        var pdfReaderTemplate = new PdfReader(watermarkTemplatePath);
        var page = pdfStamper.GetImportedPage(pdfReaderTemplate, 1);

        for (var i = 0; i < pdfReaderSource.NumberOfPages; i++)
        {
            var content = pdfStamper.GetUnderContent(i + 1);
            content.AddTemplate(page, 0, 0);
        }

        pdfStamper.Close();
        pdfReaderTemplate.Close();
    }
andrei.ciprian
  • 2,895
  • 1
  • 19
  • 29
usha
  • 21
  • 1
  • 6
  • 1
    You are adding the watermark *under the existing content* at hard-code coordinates `x = 0; y = 0`. Maybe the pages that don't show the watermark are opaque and/or maybe they have a different coordinate system (the lower-left corner doesn't always have the coordinate `0, 0`). Without seeing the actual PDF you want to watermark, we can't really help. Did you read [How to add a watermark to a page with an opaque image?](http://developers.itextpdf.com/question/how-add-watermark-page-opaque-image) & [How to watermark?](http://developers.itextpdf.com/question/how-watermark-pdfs-using-text-or-images) – Bruno Lowagie Jan 07 '16 at 10:25

1 Answers1

0

The following is inspired by 'iText in Action - 2nd Edition' by Bruno Lowagie. I am using iTextSharp version 5.4.

The code below adds both a text watermark and a transparent image watermark to an existing pdf. Details in comments...

public interface IWriter { void Write(Stream stream); }

public class TextAndImageWatermarker : IWriter 
{
  public readonly string INPUT_PDF = "the_pdf_you_are_watermarking";

  // inner class for text watermark
  class TextWatermarkPdfPageEventHelper : PdfPageEventHelper
  {
      static readonly Font FONT = new Font(Font.FontFamily.HELVETICA, 40, Font.NORMAL, new GrayColor(0.75f));

      // write text SW to NE for odd pages, NW to SE for even pages
      public override void OnEndPage(PdfWriter writer, Document document)
      {
          ColumnText.ShowTextAligned(
            writer.DirectContentUnder,
            Element.ALIGN_CENTER, new Phrase("watermark (text or image) in existing pdf", FONT),
            300, 400, writer.PageNumber % 2 == 1 ? 60 : -60
          );
      }
  }

  // inner class for image watermark
  class ImageWatermarkPdfPageEventHelper : PdfPageEventHelper
  {
      // the image you use as a watermark 
      static readonly Image img = null;

      public override void OnEndPage(PdfWriter writer, Document document)
      {
          img.SetAbsolutePosition(
              (document.PageSize.Width - img.ScaledWidth) / 4,
              (document.PageSize.Height - img.ScaledHeight) / 4
            );

          writer.DirectContentUnder.SaveState();

          writer.DirectContentUnder.SetGState(new PdfGState() { FillOpacity = 0.5f });
          writer.DirectContentUnder.AddImage(img, true);

          writer.DirectContentUnder.RestoreState();
      }
  }

  public void Write(Stream stream)
  {
      var reader = new PdfReader(INPUT_PDF);
      using (reader)
      {
          using (Document document = new Document())
          {
              // trick is to use page events
              PdfWriter writer = PdfWriter.GetInstance(document, stream);
              writer.PageEvent = new TextWatermarkPdfPageEventHelper();
              writer.PageEvent = new ImageWatermarkPdfPageEventHelper();

              document.Open();
              var n = reader.NumberOfPages;

              // dump pages from source, watermarks will be added OnEndPage
              for (int i = 1; i <= n; i++)
              {
                  document.NewPage();
                  var pagei = writer.GetImportedPage(reader, i);
                  writer.DirectContentUnder.AddTemplate(pagei, 0, 0);
              }
          }
      }
    }
}
Community
  • 1
  • 1
andrei.ciprian
  • 2,895
  • 1
  • 19
  • 29
  • This code is very destructive as far as annotations (e.g. form fields) in the source document are concerned. Furthermore a specific page format is assumed. – mkl Jan 07 '16 at 16:22
  • By Itextsharp i am getting the watermark in all the pages but by using GetUnderContent the watermark is hiding on the content and on the last page it is showing . By Using GetOverContent it is showing in all the pages but above the content the content is hiding . can you help on this? – usha Jan 08 '16 at 06:31
  • 2
    @mkl: This is not enterprise level code. Just a solution to a problem. A specific format or form fields are not the issues here. I am not doing the man's job, just giving an idea .. – andrei.ciprian Jan 08 '16 at 09:53
  • @usha: This has been tested before posting. That's why I used `DirectContentUnder`, not to write over the original doc. Same considerations for the transparent watermark. – andrei.ciprian Jan 08 '16 at 09:58
  • @andrei.ciprian *This is not enterprise level code. Just a solution to a problem* - If a solution you present has such severe side effects, you *should mention them* in your answer. – mkl Jan 08 '16 at 10:00
  • @usha this is a common problem, solutions can be found in existing answers, e.g. [this one](http://stackoverflow.com/a/24455048/1729265); the solution is for iText/Java but should be easy to translate to iTextSharp/C#. [This question](http://stackoverflow.com/q/29087283/1729265) already has working C# code in the question body itself. – mkl Jan 08 '16 at 10:15