ImageGear v26.0 - Updated
Watermarks in a PDF
Developer Guide > How to Work with ... > PDF > How to... > Manage PDF Content > Watermarks in a PDF

A digital watermark is any auxiliary data embedded into a document used for subsequent identification. Watermarks may provide contextual support to an author's content, but are otherwise independent of that content. For example, stamping a page as "DRAFT" or "CONFIDENTIAL" imparts meaning beyond any text or drawings present on that page.

For sample code, refer to the AddWatermarkToPDFPage sample. See Samples and Demos.

PDF documents may express a digital watermark using any of the following techniques:

Each of these techniques can be accomplished using ImageGear, with varying complexity and completeness. See the following subsections:

Annotations

ImageGear does not support creating or editing PDF annotations.

Page Graphics

Watermarks expressed as PDF page graphics are added using the ImageGear.Formats.PDF namespace. This namespace provides classes for content editing modeled after graphics objects and operators described in the PDF Reference.

The following snippet demonstrates placing a 24-bpp RGB bitmap at the bottom left corner of a PDF page:

PDF support needs to be initialized first for this snippet to work. To get familiar with initializing IGNET, initializing PDF support, loading a PDF, saving a PDF, and terminating PDF support, try any one of the tutorials.

Adjustments are required to successfully add images utilizing other pixel formats and color spaces in accordance to the image XObject discussion in the PDF reference.

C#

using System;
using System.IO;
using System.Windows.Forms;

using ImageGear.Core;
using ImageGear.Formats;
using ImageGear.Formats.PDF;

public static void AddRGB24ImageToPdfPage(ImGearPDFPage igPDFPage, ImGearPage igImage)
{
   const Int32 BITS_PER_BYTE = 8;
   try
   {
       // Acquire the PDF page content.
       using (ImGearPDEContent content = igPDFPage.GetContent())
       {
           // Extract pixel data from RGB24 image.
           Int32 strideInBytes = (igImage.DIB.Width * igImage.DIB.BitDepth + BITS_PER_BYTE - 1)
                                   / BITS_PER_BYTE;
           Byte[] pixelData = new Byte[strideInBytes * igImage.DIB.Height];
           for (int row = 0; row < igImage.DIB.Height; row++)
           {
               ImGearArrayRef raster = igImage.DIB.GetRaster(row);
               Array.Copy((Byte[])raster.Content, raster.Offset, pixelData, row * strideInBytes,
                   strideInBytes);
           }

           // Create a DeviceRGB PDE Colorspace for RGB24 image.
           ImGearPDEColorSpace igPDEColorSpace = new ImGearPDEColorSpace(
               new ImGearPDFAtom("DeviceRGB"));

           // Create a PDE Image attributes for image Form XObject
           ImGearPDEImageAttrs igPDEImageAttrs = new ImGearPDEImageAttrs();
           igPDEImageAttrs.Width = igImage.DIB.Width;
           igPDEImageAttrs.Height = igImage.DIB.Height;
           igPDEImageAttrs.Flags = ImGearPDEImageAttrFlags.EXTERNAL;
           igPDEImageAttrs.BitsPerComponent = 8;

           // Create a transform matrix that places the image at the bottom-left corner
           // of the PDF page.
           ImGearPDFFixedMatrix igPDETransformMatrix = new ImGearPDFFixedMatrix();
           igPDETransformMatrix.A = ImGearPDF.DoubleToFixed(((double)igImage.DIB.Width));
           igPDETransformMatrix.B = (int)ImGearPDFFixedValues.ZERO;
           igPDETransformMatrix.C = (int)ImGearPDFFixedValues.ZERO;
           igPDETransformMatrix.D = ImGearPDF.DoubleToFixed(((double)igImage.DIB.Height));
           igPDETransformMatrix.H = (int)ImGearPDFFixedValues.ZERO;
           igPDETransformMatrix.V = (int)ImGearPDFFixedValues.ZERO;

           // Create a filter to compress RGB24 pixel data using the discrete cosine
           // transform (DCT) technique based on the JPEG standard.
           ImGearPDEFilterArray igPDEFilterArray = new ImGearPDEFilterArray();
           ImGearPDFBasDict igDict = new ImGearPDFBasDict((ImGearPDFDocument)igPDFPage.Document,
                                        false, 3);
           igDict.PutInt(new ImGearPDFAtom("Columns"), false, igImage.DIB.Width);
           igDict.PutInt(new ImGearPDFAtom("Rows"), false, igImage.DIB.Height);
           igDict.PutInt(new ImGearPDFAtom("Colors"), false, 3);
           ImGearPDEFilterSpec igPDEFilterSpec = new ImGearPDEFilterSpec();
           igPDEFilterSpec.Name = new ImGearPDFAtom("DCTDecode");
           igPDEFilterSpec.DecodeParams = igDict;
           igPDEFilterSpec.EncodeParams = igDict;
           igPDEFilterArray.AddSpec(igPDEFilterSpec);

           // Create the PDE image.
           using (ImGearPDEImage igPDEImage = new ImGearPDEImage(igPDEImageAttrs,
                   igPDETransformMatrix, ImGearPDEImageDataFlags.DECODED, igPDEColorSpace, null,
                   igPDEFilterArray, null, pixelData))
           {
               // Add the PDEImage to the PDF page graphics.
               content.AddElement((int)ImGearPDEInsertElement.AFTER_LAST, igPDEImage);
               igPDFPage.SetContent();

               // Force refresh of PDF page content.
               igPDFPage.ResetDisplayCache();
           }
       }
   }
   finally
   {
       // Release the PDF page content.
       igPDFPage.ReleaseContent();
   }
}

Refer to the AddWatermarkToPDFPage sample. See Samples and Demos.

See the PDF Reference topic "Graphics" for additional information.

See ImGearPDFFixedMatrix Class for information about defining a transformation matrix.

Optional Content Groups

Watermark optional content can be added to PDF pages using the ImageGear.Formats.PDF namespace, which provides classes for layer management.

Refer to Containers, Dictionaries, and Layers for guidance on using the ImageGear.Formats.PDF namespace to manage watermarks with Optional Content Groups (OCG).

To designate a watermark intended for printing, add an Optional Content Print Usage dictionary with Subtype name "Watermark" to that OCG, represented with an ImGearPDFLayer object:

C#

// Create Print Usage dictionary
ImGearPDFBasDict igPrintUsageDict = new ImGearPDFBasDict( igPDFDocument, false, 2 );
igPrintUsageDict.PutName( new ImGearPDFAtom("Subtype"), false, new ImGearPDFAtom( "Watermark" ));
igPrintUsageDict.PutName( new ImGearPDFAtom("PrintState"), false, new ImGearPDFAtom( "ON" ));

// Add Print Usage dictionary to OCG group named "WatermarkLayer"
ImGearPDFLayer igWatermarkLayer = igPDFDocument.CreateLayer( "WatermarkLayer" );
igWatermarkLayer.SetUsageInfo( new ImGearPDFAtom("Print"), igPrintUsageDict );

See the PDF Reference topic "Making Graphical Content Optional" for additional information.

Pagination Artifacts

Watermarks expressed as Pagination Artifacts can be added using the ImageGear.Formats.PDF namespace, which provides classes to create a marked-content sequence in accordance with the PDF Reference.

This usage is not demonstrated in any sample presently.

See the PDF Reference topic "Real Content and Artifacts" for additional information.

Is this page helpful?
Yes No
Thanks for your feedback.