Agrega una marca de agua a las páginas de un documento PDF en .NET
Categoría del blog: PDF ; .NET
11.09.2020
// The project, which uses this code, must have references to the following assemblies:
// - Vintasoft.Imaging
// - Vintasoft.Imaging.Pdf
/// <summary>
/// Adds the watermark image to the PDF document.
/// </summary>
/// <param name="inPdfFilename">The filename of input PDF document.</param>
/// <param name="outPdfFilename">The filename of output PDF document.</param>
/// <param name="watermarkImageFilename">The filename of watermark image.</param>
public static void AddWatermarkToPdfDocument(string inPdfFilename, string outPdfFilename, string watermarkImageFilename)
{
    AddWatermarkToPdfDocument(inPdfFilename, outPdfFilename, watermarkImageFilename, 0.25f, new Vintasoft.Imaging.PaddingF(0.1f), false);
}
/// <summary>
/// Adds the watermark image to the PDF document.
/// </summary>
/// <param name="inPdfFilename">The filename of input PDF document.</param>
/// <param name="outPdfFilename">The filename of output PDF document.</param>
/// <param name="watermarkImageFilename">The filename of watermark image.</param>
/// <param name="watermarkImageAlpha">The watermark image alpha.</param>
/// <param name="watermarkImagePadding">The watermark image padding.</param>
/// <param name="ignorePageRotation">Indicates that value of Vintasoft.Imaging.Pdf.Tree.PdfPage.Rotate property should be ignored.</param>
public static void AddWatermarkToPdfDocument(
    string inPdfFilename,
    string outPdfFilename,
    string watermarkImageFilename, 
    float watermarkImageAlpha,
    Vintasoft.Imaging.PaddingF watermarkImagePadding,
    bool ignorePageRotation)
{
    // check watermark padding
    if (watermarkImagePadding.Horizontal < 0 || watermarkImagePadding.Vertical < 0)
        throw new System.ArgumentOutOfRangeException("watermarkImagePadding");
    // open PDF document
    using (Vintasoft.Imaging.Pdf.PdfDocument document = new Vintasoft.Imaging.Pdf.PdfDocument(inPdfFilename))
    {
        // create "watermark" resource
        Vintasoft.Imaging.Pdf.Tree.PdfResource watermakResource;
        using (Vintasoft.Imaging.VintasoftImage watermarkImage = new Vintasoft.Imaging.VintasoftImage(watermarkImageFilename))
        {
            // if watermarkImage is PDF page
            if (watermarkImage.SourceInfo.DecoderName == "Pdf")
            {
                // create form resource based on PDF page
                Vintasoft.Imaging.Pdf.Tree.PdfPage page = Vintasoft.Imaging.Pdf.PdfDocumentController.GetPageAssociatedWithImage(watermarkImage);
                watermakResource = new Vintasoft.Imaging.Pdf.Tree.PdfFormXObjectResource(document, page);
            }
            else
            {
                // create watermark image resource with JPEG compression
                Vintasoft.Imaging.Pdf.PdfCompression watermarkResourceCompression = Vintasoft.Imaging.Pdf.PdfCompression.Jpeg;
                watermakResource = new Vintasoft.Imaging.Pdf.Tree.PdfImageResource(document, watermarkImage, watermarkResourceCompression);
            }
        }
        // for each page in PDF document
        foreach (Vintasoft.Imaging.Pdf.Tree.PdfPage page in document.Pages)
        {
            // add watermark on PDF page
            AddWatermarkToPdfPage(page, watermakResource, watermarkImagePadding, watermarkImageAlpha, ignorePageRotation);
        }
        // pack PDF document to an output file
        document.Pack(outPdfFilename);
    }
}
/// <summary>
/// Adds the watermark image to the PDF page.
/// </summary>
/// <param name="page">The PDF page.</param>
/// <param name="watermarkResource">The PDF resource that contains watermark.</param>
/// <param name="watermarkImagePadding">The watermark image padding.</param>
/// <param name="watermarkImageAlpha">The watermark image alpha.</param>
/// <param name="ignorePageRotation">Indicates that value of Vintasoft.Imaging.Pdf.Tree.PdfPage.Rotate property should be ignored.</param>
public static void AddWatermarkToPdfPage(
    Vintasoft.Imaging.Pdf.Tree.PdfPage page,
    Vintasoft.Imaging.Pdf.Tree.PdfResource watermarkResource,
    Vintasoft.Imaging.PaddingF watermarkImagePadding,
    float watermarkImageAlpha,
    bool ignorePageRotation)
{
    Vintasoft.Imaging.Pdf.Tree.PdfImageResource watermarkImageResource = watermarkResource as Vintasoft.Imaging.Pdf.Tree.PdfImageResource;
    Vintasoft.Imaging.Pdf.Tree.PdfFormXObjectResource watermarkFormResource = watermarkResource as Vintasoft.Imaging.Pdf.Tree.PdfFormXObjectResource;
    // gets the size of watermark resource
    System.Drawing.SizeF watermarkResourceSize;
    if (watermarkImageResource != null)
        watermarkResourceSize = new System.Drawing.SizeF(watermarkImageResource.Width, watermarkImageResource.Height);
    else
        watermarkResourceSize = new System.Drawing.SizeF(watermarkFormResource.BoundingBox.Width, watermarkFormResource.BoundingBox.Height);
    // create PDF graphics from PDF page and specify that graphics must clear and add new content
    using (Vintasoft.Imaging.Pdf.Drawing.PdfGraphics graphics = Vintasoft.Imaging.Pdf.Drawing.PdfGraphics.FromPage(page))
    {
        // get mediabox of PDF page
        System.Drawing.RectangleF pageMediaBox = page.MediaBox;
        // if watermark image must be rotated
        if (!ignorePageRotation && page.Rotate != 0)
        {
            // rotate padding
            watermarkImagePadding.Rotate(page.Rotate);
        }
        // calculate watermark rectangle
        System.Drawing.RectangleF watermarkRect = new System.Drawing.RectangleF(
            pageMediaBox.X + watermarkImagePadding.Left * pageMediaBox.Width,
            pageMediaBox.Y + watermarkImagePadding.Bottom * pageMediaBox.Height,
            pageMediaBox.Width - watermarkImagePadding.Horizontal * pageMediaBox.Width,
            pageMediaBox.Height - watermarkImagePadding.Vertical * pageMediaBox.Height);
        float scale = System.Math.Min(watermarkRect.Width / watermarkResourceSize.Width, watermarkRect.Height / watermarkResourceSize.Height);
        System.Drawing.RectangleF watermarkImageRect = new System.Drawing.RectangleF(
            watermarkRect.X + (watermarkRect.Width - watermarkResourceSize.Width * scale) / 2,
            watermarkRect.Y + (watermarkRect.Height - watermarkResourceSize.Height * scale) / 2,
            watermarkResourceSize.Width * scale,
            watermarkResourceSize.Height * scale);
        // create graphics state parameters
        Vintasoft.Imaging.Pdf.Tree.PdfGraphicsStateParameters gsParams = new Vintasoft.Imaging.Pdf.Tree.PdfGraphicsStateParameters(page.Document);
        // set blending mode to "Multiply"
        gsParams.BlendMode = Vintasoft.Imaging.Pdf.Tree.GraphicsStateBlendMode.Multiply;
        // set alpha transparency
        gsParams.AlphaForNonStrokingOperations = watermarkImageAlpha;
        // save graphics state
        graphics.SaveGraphicsState();
        // set graphics state parameters
        graphics.SetGraphicsStateParameters(gsParams);
        // if watermark image must be rotated
        if (!ignorePageRotation && page.Rotate != 0)
        {
            // apply rotation to the PdfGraphics
            Vintasoft.Imaging.AffineMatrix matrix = new Vintasoft.Imaging.AffineMatrix();
            matrix.RotateAt(
                page.Rotate,
                watermarkImageRect.X + watermarkImageRect.Width / 2,
                watermarkImageRect.Y + watermarkImageRect.Height / 2);
            graphics.MultiplyTransform(matrix);
        }
        // if watermark is an image
        if (watermarkImageResource != null)
            // draw watermark image
            graphics.DrawImage(watermarkImageResource, watermarkImageRect);
        else
            // draw watermark form
            graphics.DrawForm(watermarkFormResource, watermarkImageRect);
        // restore graphics state
        graphics.RestoreGraphicsState();
    }
}