Aggiungi una filigrana alle pagine del documento PDF in .NET

Categoria del blog: PDF.NET

11.09.2020

Una "filigrana" è un testo o un'immagine che appare davanti al contenuto di un documento esistente. Ad esempio, è possibile applicare una filigrana "Riservata" alle pagine PDF contenenti informazioni sensibili.

L'edizione "PDF Reader+Writer" del VintaSoft PDF .NET Plug-in fornisce funzionalità per aggiungere filigrane alle pagine di documenti PDF.

Per non sovrapporre il testo del documento PDF, la filigrana deve essere aggiunta in modalità di fusione dei colori "Moltiplica".
Viene utilizzata una risorsa filigrana per tutte le pagine del documento per creare un PDF con dimensioni ottimali.
Un documento PDF con immagine raster o vettoriale può essere definito come filigrana.

Ecco il codice C# che consente di aggiungere una filigrana in un documento PDF:
// 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();
    }
}     


Ecco un esempio di documento PDF in cui ogni pagina contiene la filigrana aggiunta: testDocument_marked.pdf.