【问题标题】:watermark (text or image) in existing pdf现有 pdf 中的水印(文本或图像)
【发布时间】:2016-04-11 11:41:34
【问题描述】:

如何在 c# 中的现有 pdf 中添加水印(文本或图像)?

我希望为 pdf 的所有页面显示水印。

我尝试使用 itextsharp,但水印仅显示在 pdf 的最后一页。

    public void CreateTemplate(string watermarkText, string targetFileName)
    {
        var document = new Document();
        var pdfWriter = PdfWriter.GetInstance(document, new FileStream(targetFileName, FileMode.Create));
        var font = new iTextSharp.text.Font(iTextSharp.text.Font.HELVETICA, 60, iTextSharp.text.Font.NORMAL, iTextSharp.text.Color.LIGHT_GRAY);
        document.Open();
        ColumnText.ShowTextAligned(pdfWriter.DirectContent, Element.ALIGN_CENTER, new Phrase(watermarkText, font), 300, 400, 45);
        document.Close();
    }
    public void AddTextWatermark(string sourceFilePath, string watermarkTemplatePath, string targetFilePath)
    {
        var pdfReaderSource = new PdfReader(sourceFilePath);
        var pdfStamper = new PdfStamper(pdfReaderSource, new FileStream(targetFilePath, FileMode.Create));
        var pdfReaderTemplate = new PdfReader(watermarkTemplatePath);
        var page = pdfStamper.GetImportedPage(pdfReaderTemplate, 1);

        for (var i = 0; i < pdfReaderSource.NumberOfPages; i++)
        {
            var content = pdfStamper.GetUnderContent(i + 1);
            content.AddTemplate(page, 0, 0);
        }

        pdfStamper.Close();
        pdfReaderTemplate.Close();
    }

【问题讨论】:

  • 您在硬编码坐标x = 0; y = 0 处添加水印在现有内容下。可能不显示水印的页面是不透明的和/或可能它们具有不同的坐标系(左下角并不总是具有坐标0, 0)。如果没有看到您想要添加水印的实际 PDF,我们将无能为力。你读过How to add a watermark to a page with an opaque image? & How to watermark?

标签: c# itextsharp


【解决方案1】:

以下内容的灵感来自Bruno Lowagie 的“iText in Action - 2nd Edition”。我正在使用 iTextSharp 5.4 版。

下面的代码将文本水印和透明图像水印添加到现有的 pdf 中。 cmets中的详细信息...

public interface IWriter { void Write(Stream stream); }

public class TextAndImageWatermarker : IWriter 
{
  public readonly string INPUT_PDF = "the_pdf_you_are_watermarking";

  // inner class for text watermark
  class TextWatermarkPdfPageEventHelper : PdfPageEventHelper
  {
      static readonly Font FONT = new Font(Font.FontFamily.HELVETICA, 40, Font.NORMAL, new GrayColor(0.75f));

      // write text SW to NE for odd pages, NW to SE for even pages
      public override void OnEndPage(PdfWriter writer, Document document)
      {
          ColumnText.ShowTextAligned(
            writer.DirectContentUnder,
            Element.ALIGN_CENTER, new Phrase("watermark (text or image) in existing pdf", FONT),
            300, 400, writer.PageNumber % 2 == 1 ? 60 : -60
          );
      }
  }

  // inner class for image watermark
  class ImageWatermarkPdfPageEventHelper : PdfPageEventHelper
  {
      // the image you use as a watermark 
      static readonly Image img = null;

      public override void OnEndPage(PdfWriter writer, Document document)
      {
          img.SetAbsolutePosition(
              (document.PageSize.Width - img.ScaledWidth) / 4,
              (document.PageSize.Height - img.ScaledHeight) / 4
            );

          writer.DirectContentUnder.SaveState();

          writer.DirectContentUnder.SetGState(new PdfGState() { FillOpacity = 0.5f });
          writer.DirectContentUnder.AddImage(img, true);

          writer.DirectContentUnder.RestoreState();
      }
  }

  public void Write(Stream stream)
  {
      var reader = new PdfReader(INPUT_PDF);
      using (reader)
      {
          using (Document document = new Document())
          {
              // trick is to use page events
              PdfWriter writer = PdfWriter.GetInstance(document, stream);
              writer.PageEvent = new TextWatermarkPdfPageEventHelper();
              writer.PageEvent = new ImageWatermarkPdfPageEventHelper();

              document.Open();
              var n = reader.NumberOfPages;

              // dump pages from source, watermarks will be added OnEndPage
              for (int i = 1; i <= n; i++)
              {
                  document.NewPage();
                  var pagei = writer.GetImportedPage(reader, i);
                  writer.DirectContentUnder.AddTemplate(pagei, 0, 0);
              }
          }
      }
    }
}

【讨论】:

  • 就源文档中的注释(例如表单字段)而言,此代码具有很大的破坏性。此外,还假定了特定的页面格式。
  • 通过 Itextsharp,我在所有页面中都获得了水印,但通过使用 GetUnderContent,水印隐藏在内容和显示的最后一页上。通过使用 GetOverContent,它显示在所有页面中,但在内容隐藏的内容之上。你能帮忙吗?
  • @mkl:这不是企业级代码。只是一个问题的解决方案。特定格式或表单字段不是这里的问题。我不是在做男人的工作,只是给出一个想法..
  • @usha:这在发布前已经过测试。这就是我使用DirectContentUnder 的原因,而不是覆盖原始文档。透明水印的注意事项相同。
  • @andrei.ciprian 这不是企业级代码。只是解决问题 - 如果您提出的解决方案有如此严重的副作用,您应该在回答中提及。
猜你喜欢
  • 2018-12-02
  • 1970-01-01
  • 2011-02-12
  • 2014-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多