2017-01-17 3 views
-1

У меня есть документ в формате pdf, на который я добавил водяной знак. Результат хороший, но если я попытаюсь подчеркнуть приведенный pdf, то водяной знак увидит, как часть документа текста, поэтому результат подчеркивания неверен.
Вот мой код, используемый для применения водяного знака:Подчеркните документ с водяным знаком в iTextSharp

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; 
    } 
} 
+0

ли «подчеркивание» означает добавление подписи? Вам также нужно будет показать этот код, так как вы заявляете, что добавление водяного знака приводит к желаемому результату, но ломается при добавлении большего количества документа. – Filburt

+0

@Filburt Я редактирую окончательный pdf (оригинальный + водяной знак) с помощью pspdfkit sdk на Android. «подчеркивание» означает сделать аннотацию и подчеркнуть текст документа, а не подпись. – Marco

+1

Спасибо за разъяснение. Важно, чтобы вы упоминали pspdfkit, так как у вас может сложиться впечатление, что вы делаете подчеркивающую часть, также используя itextsharp. – Filburt

ответ

0

Я нашел это решение. Преобразуйте в pdf-файл водяного знака в изображение, и я добавлю это изображение и добавлю его на каждую страницу окончательного pdf. Я использовал библиотеку PdfiumViewer для преобразования страницы Pdf в PNG-изображение.
Вот код:

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(); 
} 
+0

Рендеринг pdf в виде растрового изображения, конечно, имеет обратную сторону пониженного качества ... – mkl