PDF watermarks

A PDF watermark is a recognizable image or pattern in page used to identify authenticity or to convey some information about the document status (Confidential for example).

Since the watermark is not a predefined PDF object, its content is usually defined by the business requirements and it can be any combination of text, graphics and images.
For example the evaluation version of our library XFINIUM.PDF add this text to document’s pages: “Created with XFINIUM.PDF”. This text can be considered a watermark.

Inside the page content there are no markers specifying that a sequence of graphic objects represent the watermark, the watermark is something that we identify visually when we look at the document.
From the point of view of page content the watermark content is regular page content, like any other text or image on the page.

PDF watermarks can be created in many ways, each one with pros and cons.

1. Draw the watermark under page content.

This is a usual method for drawing a watermark on the page because the watermark content does not hide the page content. The problem appears when the page content consists of scanned images or any other massive opaque objects.
In this scenario the watermark content is blocked by the page content and it is not visible.
This type of watermark can be created like this:

// Load the document to be watermarked
PdfFixedDocument document = new PdfFixedDocument("source.pdf");
// Draw the watermark on every page
PdfStandardFont font = new PdfStandardFont(PdfStandardFontFace.HelveticaBold, 36);
PdfBrush brush = new PdfBrush();
for (int i = 0; i < document.Pages.Count; i++)
{    
    // Set the page Graphics to be located under existing page content    
    document.Pages[i].SetGraphicsPosition(PdfPageGraphicsPosition.UnderExistingPageContent);     
    //    
    // Draw the watermark content on the page    
    //
    document.Pages[i].Graphics.DrawString("XFINIUM.PDF", font, brush, 0, 0);
}
document.Save("watermaked.pdf");
' Load the document to be watermarked
Dim document As New PdfFixedDocument("source.pdf")
' Draw the watermark on every page
Dim font As New PdfStandardFont(PdfStandardFontFace.HelveticaBold, 36)
Dim brush As New PdfBrush()
For i As Integer = 0 To document.Pages.Count - 1 
    ' Set the page Graphics to be located under existing page content  
    document.Pages(i).SetGraphicsPosition(PdfPageGraphicsPosition.UnderExistingPageContent)
    '  
    ' Draw the watermark content on the page  
    ' 
    document.Pages(i).Graphics.DrawString("XFINIUM.PDF", font, brush, 0, 0)
Next
document.Save("watermaked.pdf")

The image below shows how an under page content watermark looks like.
Watermark under page content

2. Draw the watermark over the page content.

This method solves the previous problem with scanned page content but introduces another, the watermark content blocks the page content. This method can be used when it is know that the watermark location on the page is always empty.

// Load the document to be watermarked
PdfFixedDocument document = new PdfFixedDocument("source.pdf");
// Draw the watermark on every page
PdfStandardFont font = new PdfStandardFont(PdfStandardFontFace.HelveticaBold, 36);
PdfBrush brush = new PdfBrush();
for (int i = 0; i < document.Pages.Count; i++)
{
    // By default the page Graphics is located over the existing page content so no need to call this.
    // document.Pages[i].SetGraphicsPosition(PdfPageGraphicsPosition.OverExistingPageContent);

    //
    // Draw the watermark content on the page
    //
    document.Pages[i].Graphics.DrawString("XFINIUM.PDF", font, brush, 0, 0);
}
document.Save("watermaked.pdf");
' Load the document to be watermarked
Dim document As New PdfFixedDocument("source.pdf")
' Draw the watermark on every page
Dim font As New PdfStandardFont(PdfStandardFontFace.HelveticaBold, 36)
Dim brush As New PdfBrush()
For i As Integer = 0 To document.Pages.Count - 1
    ' By default the page Graphics is located over the existing page content so no need to call this.
    ' document.Pages[i].SetGraphicsPosition(PdfPageGraphicsPosition.OverExistingPageContent);

    '
    ' Draw the watermark content on the page
    '
    document.Pages(i).Graphics.DrawString("XFINIUM.PDF", font, brush, 0, 0)
Next
document.Save("watermaked.pdf")

The image below shows how an over page content watermark looks like.

A possible solution to the problem above is to draw the watermark using some level of transparency. In this way the page content is partially visible under the watermark.

// Load the document to be watermarked
PdfFixedDocument document = new PdfFixedDocument("source.pdf");
// Draw the watermark on every page
PdfStandardFont font = new PdfStandardFont(PdfStandardFontFace.HelveticaBold, 36);
PdfBrush brush = new PdfBrush();
for (int i = 0; i < document.Pages.Count; i++)
{
    // Create an extended graphics state that sets the transparency level.
    PdfExtendedGraphicState gs = new PdfExtendedGraphicState();
    gs.FillAlpha = 0.5;
    gs.StrokeAlpha = 0.5;

    // Save the page graphics state
    document.Pages[i].Graphics.SaveGraphicsState();

    // Set the transparency in the page content.
    document.Pages[i].Graphics.SetExtendedGraphicState(gs);

    //
    // Draw the watermark content on the page
    //
    document.Pages[i].Graphics.DrawString("XFINIUM.PDF", font, brush, 0, 0);

    // Restore the transparency to initial level.
    document.Pages[i].Graphics.RestoreGraphicsState();
}
document.Save("watermaked.pdf");
' Load the document to be watermarked
Dim document As New PdfFixedDocument("source.pdf")
' Draw the watermark on every page
Dim font As New PdfStandardFont(PdfStandardFontFace.HelveticaBold, 36)
Dim brush As New PdfBrush()
For i As Integer = 0 To document.Pages.Count - 1
    ' Create an extended graphics state that sets the transparency level.
    Dim gs As New PdfExtendedGraphicState()
    gs.FillAlpha = 0.5
    gs.StrokeAlpha = 0.5

    ' Save the page graphics state
    document.Pages(i).Graphics.SaveGraphicsState()

   ' Set the transparency in the page content.
   document.Pages(i).Graphics.SetExtendedGraphicState(gs)

   '
   ' Draw the watermark content on the page
   '
    document.Pages(i).Graphics.DrawString("XFINIUM.PDF", font, brush, 0, 0)

   ' Restore the transparency to initial level.
   document.Pages(i).Graphics.RestoreGraphicsState()
Next
document.Save("watermaked.pdf")

The image below shows how the transparent watermark looks like.

Another possible solution to the problem above is to draw the watermark using a blend mode that lets both the page content and watermark content to be visible but in a different color.

// Load the document to be watermarked
PdfFixedDocument document = new PdfFixedDocument("source.pdf");
// Draw the watermark on every page
PdfStandardFont font = new PdfStandardFont(PdfStandardFontFace.HelveticaBold, 36);
PdfBrush brush = new PdfBrush();
for (int i = 0; i < document.Pages.Count; i++)
{
    // Create an extended graphics state that sets the transparency level.
    PdfExtendedGraphicState gs = new PdfExtendedGraphicState();
    gs.BlendMode = PdfBlendMode.Luminosity;

    // Save the page graphics state
    document.Pages[i].Graphics.SaveGraphicsState();

    // Set the blend mode in the page content.
    document.Pages[i].Graphics.SetExtendedGraphicState(gs);

    //
    // Draw the watermark content on the page
    //
    document.Pages[i].Graphics.DrawString("XFINIUM.PDF", font, brush, 0, 0);

    // Restore the blend mode to normal.
    document.Pages[i].Graphics.RestoreGraphicsState();
}
document.Save("watermaked.pdf");
' Load the document to be watermarked
Dim document As New PdfFixedDocument("source.pdf")
' Draw the watermark on every page
Dim font As New PdfStandardFont(PdfStandardFontFace.HelveticaBold, 36)
Dim brush As New PdfBrush()
For i As Integer = 0 To document.Pages.Count - 1
    ' Create an extended graphics state that sets the transparency level.
    Dim gs As New PdfExtendedGraphicState()
    gs.BlendMode = PdfBlendMode.Luminosity

   ' Save the page graphics state
   document.Pages(i).Graphics.SaveGraphicsState()

   ' Set the blend mode in the page content.
   document.Pages(i).Graphics.SetExtendedGraphicState(gs)

   '
   ' Draw the watermark content on the page
   '
    document.Pages(i).Graphics.DrawString("XFINIUM.PDF", font, brush, 0, 0)

   ' Restore the blend mode to normal.
   document.Pages(i).Graphics.RestoreGraphicsState()
Next
document.Save("watermaked.pdf")

The image below shows how the blend mode watermark looks like.

Blended watermark over page content

As you can see there is no perfect solution to adding watermarks on PDF pages, you have to select the one that works best for your scenario.

Download XFINIUM.PDF library and give it a try.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.