Search code examples
c#pdfitextpspdfkit

Underline a document with watermark in iTextSharp


I have a pdf document to which I added a watermark. The result is good, but if i try to underline the resulted pdf, the watermark is seen how part of the text's document, so the underline result is wrong.
Here my code used to apply the watermark:

using (System.IO.MemoryStream memWatermark = new MemoryStream(pdfWatermark))
using (System.IO.MemoryStream memIn = new MemoryStream(pdfin))
using (System.IO.MemoryStream memOut = new MemoryStream())
{
    memWatermark.Position = 0;
    memIn.Position = 0;
    memOut.Position = 0;
    PdfReader reader = new PdfReader(memIn);
    PdfReader wmReader = new PdfReader(memWatermark);

    int j = wmReader.NumberOfPages;
    if (wmReader.NumberOfPages > 0) 
    {       
        Rectangle wmSize = wmReader.GetPageSize(1);
        int wmRotation = wmReader.GetPageRotation(1);

        using (Document doc = new Document(wmSize))
        {
            PdfWriter writer = PdfWriter.GetInstance(doc, memOut);
            doc.Open();

            PdfImportedPage waterMarkPage = writer.GetImportedPage(wmReader, 1);
            PdfImportedPage currentPage;
            for (int i = 1; i <= reader.NumberOfPages; i++)
            {
                currentPage = writer.GetImportedPage(reader, i);

                //Add the first file to coordinates 0,0
                if (wmRotation == 90 || wmRotation == 270)
                {
                    writer.DirectContent.AddTemplate(currentPage, 0, -1f, 1f, 0, 0, wmReader.GetPageSizeWithRotation(i).Height);
                }
                else
                {
                    writer.DirectContent.AddTemplate(currentPage, 1f, 0, 0, 1f, 0, 0);
                }

                // set transparency for watermark
                var gstate = new PdfGState { FillOpacity = 0.2f, StrokeOpacity = 0.4f };
                writer.DirectContent.SaveState();
                writer.DirectContent.SetGState(gstate);

                //Since we don't call NewPage the next call will operate on the same page
                if (wmRotation == 90 || wmRotation == 270)
                {
                    writer.DirectContent.AddTemplate(waterMarkPage, 0, -1f, 1f, 0, 0, wmReader.GetPageSizeWithRotation(1).Height);
                }
                else
                {
                    writer.DirectContent.AddTemplate(waterMarkPage, 1f, 0, 0, 1f, 0, 0);
                }

                // reset transparency state to default before adding next page
                writer.DirectContent.RestoreState();

                // now move to following page
                if (i < reader.NumberOfPages)
                {
                    doc.NewPage();
                }
            }

            // flush writer but leave the stream open!
            writer.Flush();
            writer.CloseStream = false;
        }
    }
    memOut.Position = 0;
    if (memOut.Length > 0)
    {
        pdfout = new byte[memOut.Length];
        pdfout = memOut.ToArray();
        done = true;
    }
}

Solution

  • I found this solution. Transform watermark's pdf page in an Image and I add that image and add it to each page of the final pdf. I used PdfiumViewer library to convert the Pdf page into a PNG image.
    Here the code:

    using (System.IO.MemoryStream memIn = new MemoryStream(pdfin))
    using (System.IO.MemoryStream memOut = new MemoryStream())
    {
        byte[] image = null;
    
        using (System.IO.MemoryStream memWatermark = new MemoryStream(pdfWatermark))                                        
        using (var document = PdfiumViewer.PdfDocument.Load(memWatermark))
        {
           using (var ms = new MemoryStream())
           {
               document.Render(0, 300, 300, true).Save(ms, System.Drawing.Imaging.ImageFormat.Png);
               image = ms.ToArray();
           }
        }
    
        PdfReader reader = new PdfReader(memIn);
        int n = reader.NumberOfPages;
        PdfStamper stamper = new PdfStamper(reader, memOut);
    
    
        // transparency
        PdfGState gs1 = new PdfGState();
        gs1.StrokeOpacity = 0.4f;
        gs1.FillOpacity = 0.2f;
    
        // properties
        PdfContentByte over;
        iTextSharp.text.Rectangle pagesize;
        float x, y;
    
    
        stamper.FormFlattening = true;
        stamper.FreeTextFlattening = true;
    
        iTextSharp.text.Rectangle wmSize = reader.GetPageSize(1);
        int wmRotation = reader.GetPageRotation(1);
    
        // image watermark
        var img = iTextSharp.text.Image.GetInstance(image);
        float w = img.ScaledWidth;
        float h = img.ScaledHeight;
    
    
        using (Document doc = new Document(wmSize))
        {
            PdfWriter writer = PdfWriter.GetInstance(doc, memOut);
            doc.Open();
    
            PdfImportedPage currentPage;
            for (int i = 1; i <= reader.NumberOfPages; i++)
            {
                pagesize = reader.GetPageSizeWithRotation(i);
                over = writer.DirectContent;
    
                currentPage = writer.GetImportedPage(reader, i);
                if (wmRotation == 90 || wmRotation == 270)
                    over.AddTemplate(currentPage, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(i).Height);
                else
                    over.AddTemplate(currentPage, 1f, 0, 0, 1f, 0, 0);
    
                x = (pagesize.Left + pagesize.Right) / 2;
                y = (pagesize.Top + pagesize.Bottom) / 2;
                over.SaveState();
                over.SetGState(gs1);
    
                var pageRotation = reader.GetPageRotation(i);
                if (pageRotation == 90 || pageRotation == 270)
                {
                    if (pageRotation == 90)
                    {
                        img.RotationDegrees = 180f;
                        img.SetAbsolutePosition(0, 0);
                        over.AddImage(img);
                    }
                    else
                    {
                        img.RotationDegrees = -90f;
                        img.SetAbsolutePosition(-(y / 2), (x / 2));
                        over.AddImage(img);
                    }
                }
                else
                    over.AddImage(img, w, 0, 0, h, x - (w / 2), y - (h / 2));
    
                over.RestoreState();
    
                // now move to following page
                if (i < reader.NumberOfPages)
                {
                    doc.NewPage();
                }
            }
    
            // flush writer but leave the stream open!
            writer.Flush();
            writer.CloseStream = false;
        }
    
        memOut.Position = 0;
        if (memOut.Length > 0)
        {
            pdfout = new byte[memOut.Length];
            pdfout = memOut.ToArray();
            done = true;
        }
    
        stamper.Close();
        reader.Close();
    }