【问题标题】:iTextSharp watermark not appearing on a scanned PDFiTextSharp 水印未出现在扫描的 PDF 上
【发布时间】:2019-01-04 10:04:30
【问题描述】:

我有一些代码用于使用 iTextSharp 为 PDF 添加水印。该代码适用于大多数 PDF,但有一个测试用例,水印在扫描文档的 PDF 上不可见。 (不过,我还有其他扫描的文档确实出现了)。

我正在使用GetOverContent() 方法。

这是我添加水印的代码;

using (PdfReader reader = new PdfReader(this.inputFilename))
{
    // Set transparent  - 1
    PdfGState gstate = new PdfGState();
    gstate.FillOpacity = 0.4f;
    gstate.StrokeOpacity = 0.5f;
    // 2
    BaseFont baseFont = BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, Encoding.ASCII.EncodingName, false);

    using (var stream = new MemoryStream())
    {
        var pdfStamper = new PdfStamper(reader, stream);

        // Must start at 1 because 0 is not an actual page.
        for (int i = 1; i <= reader.NumberOfPages; i++)
        {
            Rectangle pageSize = reader.GetPageSizeWithRotation(i);

            // Gets the content ABOVE the PDF, Another option is GetUnderContent(...)  
            // which will place the text below the PDF content. 
            PdfContentByte pdfPageContents = pdfStamper.GetOverContent(i);
            pdfPageContents.BeginText(); // Start working with text.

            // 1 
            pdfPageContents.SaveState();
            pdfPageContents.SetGState(gstate);

            float hypotenuse = (float)Math.Sqrt(Math.Pow(pageSize.Width, 2) + Math.Pow(pageSize.Height, 2));
            float glyphWidth = baseFont.GetWidth("My watermark text");
            float fontSize = 1000 * (hypotenuse * 0.8f) / glyphWidth;
            float angle = (float)(Math.Atan(pageSize.Height / pageSize.Width) * (180 / Math.PI));

            // Create a font to work with 
            pdfPageContents.SetFontAndSize(baseFont, fontSize);
            pdfPageContents.SetRGBColorFill(128, 128, 128); // Sets the color of the font, GRAY in this instance

            // Note: The x,y of the Pdf Matrix is from bottom left corner. 
            // This command tells iTextSharp to write the text at a certain location with a certain angle.
            // Again, this will angle the text from bottom left corner to top right corner and it will 
            // place the text in the middle of the page. 
            pdfPageContents.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "My watermark text", pageSize.Width / 2, pageSize.Height / 2, angle);
            pdfPageContents.EndText(); // Done working with text
            pdfPageContents.RestoreState();
        }

        pdfStamper.FormFlattening = true; // enable this if you want the PDF flattened. 
        pdfStamper.FreeTextFlattening = true; // enable this if you want the PDF flattened. 
        pdfStamper.Close(); // Always close the stamper or you'll have a 0 byte stream. 

        return stream.ToArray();
    }
}

有没有人知道为什么水印可能没有出现以及我可以尝试解决什么问题?

亲切的问候。

【问题讨论】:

  • 请分享代码失败的例子。
  • 很遗憾我不能,因为唯一的示例 PDF 包含机密信息。
  • 好吧,乍一看,甚至记录了代码中的错误,“Pdf 矩阵的 x,y 来自左下角” - 这并不总是正确的,坐标的原点可以在任何地方(在合理范围内),它只是经常在左下角。因此,也要考虑Rectangle pageSize 的左下角坐标。如果这不能解决问题,我不知道没有示例文档。
  • 感谢您指出这一点。我会做一些进一步的调查来检查一下。
  • 感谢 mkl,您绝对是正确的!我曾假设页面左下角的坐标为 (0,0),但对于本文档,坐标为 (0, 7022)。定位文本时,我没有考虑 LEFT 和 BOTTOM 起始值。非常感谢您的提示! :-)

标签: c# itext pdf-generation


【解决方案1】:

代码基于一个假设,它甚至记录为事实:

// Note: The x,y of the Pdf Matrix is from bottom left corner. 
// This command tells iTextSharp to write the text at a certain location with a certain angle.
// Again, this will angle the text from bottom left corner to top right corner and it will 
// place the text in the middle of the page. 
pdfPageContents.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "My watermark text", pageSize.Width / 2, pageSize.Height / 2, angle);

不幸的是,Pdf 矩阵的 x,y 来自左下角的假设是错误的:虽然确实经常出现 PDF 坐标系的原点(默认用户空间坐标系,更准确地说)在页面的左下角,这是不需要,原点实际上可以在任何地方(在合理的范围内)。

因此,也必须考虑Rectangle pageSize 的左下角坐标。

同时OP已经确认:

我曾假设页面左下角的坐标为 (0,0),但本文档的坐标为 (0, 7022)。

【讨论】:

    猜你喜欢
    • 2016-06-02
    • 1970-01-01
    • 2012-11-01
    • 1970-01-01
    • 2012-02-04
    • 1970-01-01
    • 2011-01-23
    • 2018-05-31
    相关资源
    最近更新 更多