-1

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;
    }
}
Filburt
  • 17,626
  • 12
  • 64
  • 115
Marco
  • 656
  • 9
  • 28
  • Does "underline" mean adding a signature? You'll need to show that code as well since you state that adding the watermark itself produced the desired result but break when adding more to the document. – Filburt Jan 17 '17 at 09:04
  • @Filburt I'm editing the final pdf (original+watermark) with pspdfkit sdk on Android. "underline" means make an annotation and underline the document text, not a signature. – Marco Jan 17 '17 at 09:27
  • 1
    Thanks for the clarification. It's important that you mentioned pspdfkit since one could get the impression you're doing the underlining part also using itextsharp. – Filburt Jan 17 '17 at 09:44
  • First of all, you have chosen a destructive watermark routine which drops all interactive content which is not the recommended way to do it. Has that been done by design? Furthermore you superimpose the watermark page onto each document page. Thus, if the contents of the original watermark PDF are subject to underlining, its superimposed representations are, too. If you don't want your watermark to disturb, use a non-disturbing watermark template to start with. – mkl Jan 17 '17 at 12:16
  • @mkl Unfortunately it isn't code written by me, I think that who did this doesn't know exactly what he did. I'm not sure that I understand your solution, please can you give me a reference on the web to understand what i need to do? – Marco Jan 17 '17 at 12:50

1 Answers1

0

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();
}
Marco
  • 656
  • 9
  • 28