ImageGear .NET v24.12 - Updated
Apply a Watermark
User Guide > How to Work with... > ART Mark Annotations > Manage Annotations > Apply a Watermark

Using ImGearRasterProcessing class methods allows you to apply a watermark to an image. A digital watermark is any auxiliary data embedded into an image used for subsequent identification. For example, stamping a raster page as "DRAFT" or "CONFIDENTIAL" imparts meaning beyond any text or drawings present on that image.

The ImGearRasterProcessing.BlendWithAlpha() method can be used to place one raster page with an alpha channel over another raster page.

The use of an alpha channel is limited to raster pages with RGB or Grayscale color space only.

Apply a watermark to a page by doing the following:

  1. Create a watermark raster page that contains an alpha channel

    A watermark raster page can be created with fixed text using ImageGear.ART methods. Annotation functionality in ImageGear provides different types of graphic objects like “Direct Text”, “Text”, “Rich Text” and others that can be printed at a fixed position and size on a page regardless of the dimensions of the printed page. To apply an annotation to the raster page, use the ImGearART.BurnIn() method.

    In addition, the watermark page may be loaded from an appropriate image file that allows storing images with alpha channel. See the What's the Best Format for...? topic for information on alpha channel support.

  2. Adjust the watermark page to the appropriate size and format and apply the watermark

    Before blending the watermark page to the image, you can change the size of the watermark using the ImGearProcessing.Resize() method. The ImGearRasterProcessing.BlendWithAlpha() method works only with images that have the same color components, therefore, before the applying the watermark to the page, adjust the bit depth using the ImGearRasterProcessing.ChangeChannelDepths() method, if necessary.

    To apply the watermark to the page, use the ImGearRasterProcessing.BlendWithAlpha() method.

1. Create a Watermark Raster Page with an Alpha Channel

You can use the ImageGear.ART namespace methods to create a text watermark. The ART namespace provides a set of methods for working with annotations. Annotations are the graphic elements that can be applied to the main page of a document. ImageGear provides a wide array of annotation marks that can be used for reviewing or updating document pages with new graphic elements.

The following example illustrates how a text based watermark page can be created using a "Text" annotation.

C#
Copy Code
using System;
using ImageGear.Core;
using ImageGear.ART;
using ImageGear.Processing;
// Creates the watermark image based on fixed text.
// isGray - The type of color space that watermark should be created for.

public static ImGearRasterPage CreateTextWatermarkPage(bool isGray)
{
     const int WATERMARK_WIDTH = 820;
     const int WATERMARK_HEIGHT = 300;
     const string WATERMARK_TEXT = "DRAFT";
     const int FULL_OPACITY = 255;
     const int HALF_TRANSPARENT = 127;
     const int NO_TRANSPARENT = 0;
     ImGearRGBQuad BLACK_COLOR = new ImGearRGBQuad(0, 0, 0);
     ImGearRGBQuad WHITE_COLOR = new ImGearRGBQuad(255, 255, 255);
     // Create text mark.
     ImGearARTText textMark = new ImGearARTText
     (
          new ImGearRectangle(WATERMARK_WIDTH, WATERMARK_HEIGHT),
          WATERMARK_TEXT,
          BLACK_COLOR,
          ImGearARTTextType.DIRECT_TEXT,
          FULL_OPACITY,
          WHITE_COLOR,
          null,
          true,
          FULL_OPACITY,
          "Arial",
          WATERMARK_HEIGHT * 0.6f,
          ImGearARTFontStyles.Bold,
          null,
          null
     );
     // Add new text mark to the created ART page;
     ImGearARTPage igArtPage = new ImGearARTPage();
     igArtPage.AddMark(textMark, ImGearARTCoordinatesType.IMAGE_COORD);
 
     // Create conversion parameters according to required color space.
     ImGearColorSpaceIDs colorspaceWithoutAlpha, colorspaceWithAlpha;
     int[] channelDepths;
     if (isGray)
     {
          colorspaceWithoutAlpha = ImGearColorSpaceIDs.Gy;
          colorspaceWithAlpha = ImGearColorSpaceIDs.GyA;
          channelDepths = new int[] { 8 };
     }
    
     else
    
     {
          colorspaceWithoutAlpha = ImGearColorSpaceIDs.RGB;
          colorspaceWithAlpha = ImGearColorSpaceIDs.RGBA;
          channelDepths = new int[] { 8, 8, 8 };
     }
     // Burn in the ART page to the new raster page.
     ImGearRasterPage page;
     page = new ImGearRasterPage
     (WATERMARK_WIDTH, WATERMARK_HEIGHT, new ImGearColorSpace(colorspaceWithoutAlpha), channelDepths, true);
     page = (ImGearRasterPage)ImGearART.BurnIn(page, igArtPage, ImGearARTBurnInOptions.ALL, null);
     // Create raster page with alpha by raster page.
     ImGearRasterProcessing.ConvertColorSpace(page, new ImGearColorSpace(colorspaceWithAlpha));
     // Set opacity for white pixels and half transparency for black pixels.
     int channelCount = channelDepths.Length + 1;
     for (int y = 0; y < page.DIB.Height; y++)
     {
          ImGearArrayRef rasterRef = page.DIB.GetRaster(y);
          byte[] content = (byte[])rasterRef.Content;
          for (int x = 0; x < page.DIB.Width * channelCount; x += channelCount)
          {
               int offset = rasterRef.Offset + x;
               bool isNoBlack = false;
               for (int index = 0; index < channelCount - 1; index++)
               {
                    if (content[offset + index] != 0)
                    {
                         isNoBlack = true;
                         break;
                    }
               }
               if (isNoBlack)
               content[offset + channelCount - 1] = NO_TRANSPARENT;
               else
               content[offset + channelCount - 1] = HALF_TRANSPARENT;
          }
     }
     return page;
}
VB.NET
Copy Code
Imports ImageGear.ART
Imports ImageGear.Processing
                
' Creates the watermark image based on fixed text.                 
' isGray - The type of color space that watermark should be created for.
Public Shared Function CreateTextWatermarkPage(isGray As Boolean) As ImGearRasterPage
Const WATERMARK_WIDTH As Integer = 820
Const WATERMARK_HEIGHT As Integer = 300
Const WATERMARK_TEXT As String = "DRAFT"
Const FULL_OPACITY As Integer = 255
Const HALF_TRANSPARENT As Integer = 127
Const NO_TRANSPARENT As Integer = 0
Dim BLACK_COLOR As New ImGearRGBQuad(0, 0, 0)
Dim WHITE_COLOR As New ImGearRGBQuad(255, 255, 255)
' Create text mark.
Dim textMark As New ImGearARTText(New ImGearRectangle(WATERMARK_WIDTH, WATERMARK_HEIGHT), WATERMARK_TEXT, BLACK_COLOR, ImGearARTTextType.DIRECT_TEXT, FULL_OPACITY, WHITE_COLOR, _
Nothing, True, FULL_OPACITY, "Arial", WATERMARK_HEIGHT * 0.6F, ImGearARTFontStyles.Bold, _
Nothing, Nothing)
' Add new text mark to the created ART page;
Dim igArtPage As New ImGearARTPage()
igArtPage.AddMark(textMark, ImGearARTCoordinatesType.IMAGE_COORD)
' Create conversion parameters according to required color space.
Dim colorspaceWithoutAlpha As ImGearColorSpaceIDs, colorspaceWithAlpha As ImGearColorSpaceIDs
Dim channelDepths As Integer()
If isGray Then
colorspaceWithoutAlpha = ImGearColorSpaceIDs.Gy
colorspaceWithAlpha = ImGearColorSpaceIDs.GyA
channelDepths = New Integer() {8}
Else
colorspaceWithoutAlpha = ImGearColorSpaceIDs.RGB
colorspaceWithAlpha = ImGearColorSpaceIDs.RGBA
channelDepths = New Integer() {8, 8, 8}
End If
' Burn in the ART page to the new raster page.
Dim page As ImGearRasterPage
page = New ImGearRasterPage(WATERMARK_WIDTH, WATERMARK_HEIGHT, New ImGearColorSpace(colorspaceWithoutAlpha), channelDepths, True)
page = DirectCast(ImGearART.BurnIn(page, igArtPage, ImGearARTBurnInOptions.ALL, Nothing), ImGearRasterPage)
' Create raster page with alpha by raster page.
ImGearRasterProcessing.ConvertColorSpace(page, New ImGearColorSpace(colorspaceWithAlpha))
' Set opacity for white pixels and half transparency for black pixels.
Dim channelCount As Integer = channelDepths.Length + 1
For y As Integer = 0 To page.DIB.Height - 1
Dim rasterRef As ImGearArrayRef = page.DIB.GetRaster(y)
Dim content As Byte() = DirectCast(rasterRef.Content, Byte())
Dim x As Integer = 0
While x < page.DIB.Width * channelCount
Dim offset As Integer = rasterRef.Offset + x
Dim isNoBlack As Boolean = False
For index As Integer = 0 To channelCount - 2
If content(offset + index) <> 0 Then
isNoBlack = True
Exit For
End If
Next
If isNoBlack Then
content(offset + channelCount - 1) = NO_TRANSPARENT
Else
content(offset + channelCount - 1) = HALF_TRANSPARENT
End If
x += channelCount
End While
Next
Return page
End Function

Loading the watermark from a file is performed in order to load the image from a file and is not discussed here. For additional information about loading images see the Loading topic.

2. Adjust the Size and Format and Apply the Watermark

The following example illustrates how to adjust the size and channel depths of the image using ImGearProcessing methods. The size of the watermark is adjusted to ¾ of the width or height of the image, depending on which is smaller. Then adjusting the channel depths is performed, and the method BlendWithAlpha applies the prepared watermark to the page.

C#
Copy Code
using System;
using ImageGear.Core;
using ImageGear.Processing;
// Adjusts the size of watermark image and applies it to the main image.
// mainPage - The raster page for watermark application.
// watermarkPage - The watermark page for application to raster page.
public static void ApplyWatermark(ImGearRasterPage mainPage, ImGearRasterPage watermarkPage)
{
     // Adjust the size of watermark image
     double scale = Math.Min(mainPage.DIB.Width / 1.5 / watermarkPage.DIB.Width, mainPage.DIB.Height / 1.5 / watermarkPage.DIB.Height);
     int width = (int)Math.Round(watermarkPage.DIB.Width * scale);
     int height = (int)Math.Round(watermarkPage.DIB.Height * scale);
     int x = mainPage.DIB.Width / 2 - width / 2;
     int y = mainPage.DIB.Height / 2 - height / 2;
     ImGearProcessing.Resize(watermarkPage, width, height, ImGearInterpolationOptions.GetDefault(ImGearInterpolations.BICUBIC));
     // Adjust the bit depth of the watermark image according to the main image.
     if (watermarkPage.DIB.ChannelDepths[0] != mainPage.DIB.ChannelDepths[0])
     {
          int[] bitDepths = new int[watermarkPage.DIB.ChannelDepths.Length];
          for (int i = 0; i < bitDepths.Length; i++)
          bitDepths[i] = mainPage.DIB.ChannelDepths[0];
          ImGearRasterProcessing.ChangeChannelDepths(watermarkPage, bitDepths);
     }
     // Apply watermark image to the main image.
     ImGearRasterProcessing.BlendWithAlpha(mainPage, x, y, watermarkPage);
}
VB.NET
Copy Code
                
' Adjusts the size of watermark image and applies it to the main image.                 
' mainPage - The raster page for watermark application.
' watermarkPage - The watermark page for application to raster page.
Public Shared Sub ApplyWatermark(mainPage As ImGearRasterPage, watermarkPage As ImGearRasterPage)
' Adjust the size of watermark image
Dim scale As Double = Math.Min(mainPage.DIB.Width / 1.5 / watermarkPage.DIB.Width, mainPage.DIB.Height / 1.5 / watermarkPage.DIB.Height)
Dim width As Integer = CInt(Math.Round(watermarkPage.DIB.Width * scale))
Dim height As Integer = CInt(Math.Round(watermarkPage.DIB.Height * scale))
Dim x As Integer = mainPage.DIB.Width / 2 - width / 2
Dim y As Integer = mainPage.DIB.Height / 2 - height / 2
ImGearProcessing.Resize(watermarkPage, width, height, ImGearInterpolationOptions.GetDefault(ImGearInterpolations.BICUBIC))
' Adjust the bit depth of the watermark image according to the main image.
If watermarkPage.DIB.ChannelDepths(0) <> mainPage.DIB.ChannelDepths(0) Then
Dim bitDepths As Integer() = New Integer(watermarkPage.DIB.ChannelDepths.Length - 1) {}
For i As Integer = 0 To bitDepths.Length - 1
bitDepths(i) = mainPage.DIB.ChannelDepths(0)
Next
ImGearRasterProcessing.ChangeChannelDepths(watermarkPage, bitDepths)
End If
' Apply watermark image to the main image.
ImGearRasterProcessing.BlendWithAlpha(mainPage, x, y, watermarkPage)
End Sub