iText 7 - 在 PDF 上添加和删除水印

iText 7 - Add and Remove Watermark on a PDF

我想使用 iText 7 在 PDF 中添加和删除水印。我可以添加水印,但无法再次删除。我只能找到与 iText 5 相关的 code/examples。感谢任何指点,谢谢。

这是我添加水印的方式(使用图层):

            pdfDoc = new PdfDocument(new PdfReader(sourceFile), new PdfWriter(destinationPath));
            var numberOfPages = pdfDoc.GetNumberOfPages();

            PageSize ps = pdfDoc.GetDefaultPageSize();

            for (var i = 1; i <= numberOfPages; i++)
            {
                PdfPage page = pdfDoc.GetPage(i);
                PdfLayer layer = new PdfLayer("watermark", pdfDoc);
                var canvas = new PdfCanvas(page);
                var pageSize = page.GetPageSize();
                var paragraph = new Paragraph(message.WatermarkText).SetFontSize(60);
                paragraph.SetFontColor(Color.BLACK, 0.2f);

                Canvas canvasModel;
                canvas.BeginLayer(layer);
                canvasModel = new Canvas(canvas, pdfDoc, ps);
                canvasModel.ShowTextAligned(paragraph, pageSize.GetWidth() / 2, pageSize.GetHeight() / 2, pdfDoc.GetPageNumber(page), TextAlignment.CENTER, VerticalAlignment.MIDDLE, 45);
                canvasModel.SetFontColor(Color.GREEN, 0.2f);
                canvas.EndLayer();
            }
            pdfDoc.Close();

这是我试过去水印的。我想完全删除它,而不仅仅是将图层设置为不显示。(感谢任何示例代码):

            pdfDoc = new PdfDocument(new PdfReader(sourceFile), new PdfWriter(destinationPath));                     
             IList<PdfLayer> layers = pdfDoc.GetCatalog().GetOCProperties(true).GetLayers();              

            for (var i = 0; i <= layers.Count; i++)
            {
                var t = layers[i].GetPdfObject().Get(PdfName.Name);

                if (t.ToString().Equals("watermark"))
                {
                        //Not what I want..need to remove the layer
                        layers[i].SetOn(false);
                        //This does not work...
                        //layers.RemoveAt(i);
                    }
                }
                pdfDoc.Close();

在 iText 的帮助下,我解决了这个问题。 如果您打算稍后删除水印,则需要将其添加为 'PDF watermark annotation'。

要在每个页面上添加水印:

    public void WatermarkPDF(string sourceFile, string destinationPath)
    {
        float watermarkTrimmingRectangleWidth = 300;
        float watermarkTrimmingRectangleHeight = 300;

        float formWidth = 300;
        float formHeight = 300;
        float formXOffset = 0;
        float formYOffset = 0;

        float xTranslation = 50;
        float yTranslation = 25;

        double rotationInRads = Math.PI / 3;

        PdfFont font = PdfFontFactory.CreateFont(FontConstants.TIMES_ROMAN);
        float fontSize = 50;

        PdfDocument pdfDoc = new PdfDocument(new PdfReader(sourceFile), new PdfWriter(destinationPath));
        var numberOfPages = pdfDoc.GetNumberOfPages();
        PdfPage page = null;

        for (var i = 1; i <= numberOfPages; i++)
        {
            page = pdfDoc.GetPage(i);
            Rectangle ps = page.GetPageSize();

            //Center the annotation
            float bottomLeftX = ps.GetWidth() / 2 - watermarkTrimmingRectangleWidth / 2;
            float bottomLeftY = ps.GetHeight() / 2 - watermarkTrimmingRectangleHeight / 2;
            Rectangle watermarkTrimmingRectangle = new Rectangle(bottomLeftX, bottomLeftY, watermarkTrimmingRectangleWidth, watermarkTrimmingRectangleHeight);

            PdfWatermarkAnnotation watermark = new PdfWatermarkAnnotation(watermarkTrimmingRectangle);

            //Apply linear algebra rotation math
            //Create identity matrix
            AffineTransform transform = new AffineTransform();//No-args constructor creates the identity transform
            //Apply translation
            transform.Translate(xTranslation, yTranslation);
            //Apply rotation
            transform.Rotate(rotationInRads);

            PdfFixedPrint fixedPrint = new PdfFixedPrint();
            watermark.SetFixedPrint(fixedPrint);
            //Create appearance
            Rectangle formRectangle = new Rectangle(formXOffset, formYOffset, formWidth, formHeight);

            //Observation: font XObject will be resized to fit inside the watermark rectangle
            PdfFormXObject form = new PdfFormXObject(formRectangle);
            PdfExtGState gs1 = new PdfExtGState().SetFillOpacity(0.6f);
            PdfCanvas canvas = new PdfCanvas(form, pdfDoc);

            float[] transformValues = new float[6];
            transform.GetMatrix(transformValues);
            canvas.SaveState()
                .BeginText().SetColor(Color.GRAY, true).SetExtGState(gs1)
                .SetTextMatrix(transformValues[0], transformValues[1], transformValues[2], transformValues[3], transformValues[4], transformValues[5])
                .SetFontAndSize(font, fontSize)
                .ShowText("watermark text")
                .EndText()
                .RestoreState();

            canvas.Release();

            watermark.SetAppearance(PdfName.N, new PdfAnnotationAppearance(form.GetPdfObject()));
            watermark.SetFlags(PdfAnnotation.PRINT);

            page.AddAnnotation(watermark);

        }
        page?.Flush();
        pdfDoc.Close();
    } 

去除水印:

    public void RemovetWatermarkPDF(string sourceFile, string destinationPath)
    {
        PdfDocument pdfDoc = new PdfDocument(new PdfReader(sourceFile), new PdfWriter(destinationPath));
        var numberOfPages = pdfDoc.GetNumberOfPages();

        for (var i = 1; i <= numberOfPages; i++)
        {
            // PdfAnnotation 
            PdfDictionary pageDict = pdfDoc.GetPage(i).GetPdfObject();
            PdfArray annots = pageDict.GetAsArray(PdfName.Annots);
            for (int j = 0; j < annots.Size(); j++)
            {
                PdfDictionary annotation = annots.GetAsDictionary(j);
                if (PdfName.Watermark.Equals(annotation.GetAsName(PdfName.Subtype)))
                {
                    annotation.Clear();
                }
            }
        }
        pdfDoc.Close();
    }

可变长度水印文本呢?您将如何动态调整矩形大小以适合文本?这不是内置在 iText 中,您需要使用以下维度参数:

float watermarkTrimmingRectangleWidth = 600;
float watermarkTrimmingRectangleHeight = 600;
float formWidth = 600;
float formHeight = 600;
float formXOffset = -100;
float fontSize = 30;

对于我的用例,我检查了水印文本的长度,并据此相应地调整了参数,例如:

        if (watermarkText.Length <= 14)
        {
            watermarkTrimmingRectangleWidth = 200;
            watermarkTrimmingRectangleHeight = 200;
            formWidth = 200;
            formHeight = 200;
            formXOffset = 0;
            fontSize = 30;
        }
        else if (watermarkText.Length <= 22)
        {
            watermarkTrimmingRectangleWidth = 300;
            watermarkTrimmingRectangleHeight = 300;
            formWidth = 300;
            formHeight = 300;
            formXOffset = 0;
            fontSize = 30;
        }
        else if (...)
        {
         ...           
        }
        .
        .
        etc.
        .
        .
        else if (watermarkText.Length <= 62)
        {
            watermarkTrimmingRectangleWidth = 600;
            watermarkTrimmingRectangleHeight = 600;
            formWidth = 600;
            formHeight = 600;
            formXOffset = -100;
            fontSize = 20;
        }