C# .NET实现为PDF添加平铺背景水印与固定水印

 更新时间:2026年06月14日 08:05:24   作者:咕白m625  
本文将介绍如何使用 Free Spire.PDF for .NET 这一免费库,通过 C# 代码为 PDF 添加平铺背景水印和局部单处水印两种文字水印效果,同时覆盖水印透明度、旋转角度等常用配置,有需要的小伙伴可以参考下

在 C# 开发中,为 PDF 文档添加文字水印是保护版权、标识文档状态或防止内容被滥用的常见需求。通过编程方式批量添加水印,比手动使用专业软件更高效、更可控。

本文将介绍如何使用 Free Spire.PDF for .NET 这一免费库,通过 C# 代码为 PDF 添加平铺背景水印局部单处水印两种文字水印效果,同时覆盖水印透明度、旋转角度等常用配置。

一、准备工作

1.1 安装 Free Spire.PDF

Free Spire.PDF 可通过 NuGet 包管理器安装,在 Visual Studio 中右键单击项目 → 管理 NuGet 程序包 → 搜索 “FreeSpire.PDF”,选择最新稳定版本安装即可。也可通过包管理器控制台执行以下命令:

Install-Package FreeSpire.PDF

注意:Free Spire.PDF 是免费社区版,唯一的限制是单次处理不能超过 10 页。如果原始 PDF 超过 10 页,超出部分不会被报错,但会被静默截断。因此该库更适合小型文档或开发/测试场景。

1.2 引入命名空间

在代码文件头部添加以下命名空间引用:

using Spire.Pdf;
using Spire.Pdf.Graphics;
using System.Drawing;

二、使用 PdfTilingBrush 绘制平铺文字水印

PdfTilingBrush 是 Free Spire.PDF 提供的平铺画刷工具。通过设置平铺单元尺寸(tileWidthtileHeight),可以让水印在页面上重复平铺,形成网格状或阵列状的水印背景。这种方式非常适合制作「文件密级」「内部资料」等背景水印效果。

以下是完整的平铺水印实现代码:

using Spire.Pdf;
using Spire.Pdf.Graphics;
using System.Drawing;

namespace TextWatermarkDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            // 加载PDF文档
            PdfDocument pdf = new PdfDocument();
            pdf.LoadFromFile("sample.pdf");

            // 设置单个水印单元的尺寸(控制水印间距,可根据需求调整)
            float tileWidth = 260f;
            float tileHeight = 260f;

            // 创建平铺画刷,覆盖页面区域
            PdfTilingBrush brush = new PdfTilingBrush(
            new SizeF(tileWidth, tileHeight));

            // 设置水印透明度(0.0 完全透明,1.0 完全不透明)
            brush.Graphics.SetTransparency(0.3f);
            // 保存图形状态
            brush.Graphics.Save();

            // 平移并旋转画布,使水印呈倾斜效果
            brush.Graphics.TranslateTransform(brush.Size.Width / 2, brush.Size.Height / 2);
            brush.Graphics.RotateTransform(-45);  // 逆时针旋转45度

            // 创建字体
            PdfTrueTypeFont font = new PdfTrueTypeFont("微软雅黑", 24f, PdfFontStyle.Regular, true);

            // 绘制水印文字
            string watermarkText = "内部文档 · 禁止外传";
            brush.Graphics.DrawString(
                watermarkText,
                font,
                PdfBrushes.Gray,
                0,
                0,
                new PdfStringFormat(PdfTextAlignment.Center, PdfVerticalAlignment.Middle));

            brush.Graphics.Restore();
            brush.Graphics.SetTransparency(1f);

            // 为每一页应用平铺画刷
            foreach (PdfPageBase page in pdf.Pages)
            {
                page.Canvas.DrawRectangle(brush, new RectangleF(0, 0, page.Canvas.ClientSize.Width, page.Canvas.ClientSize.Height));

                // 保存生成带水印的PDF
                pdf.SaveToFile("output.pdf");
            }
        }
    }
}

代码说明

  • tileWidthtileHeight 决定了每个水印单元的大小,也就是水印重复排列的间距。实际生成时,PDF 页面会被这个尺寸的单元格自动铺满,每个单元格内都包含旋转后的水印文字。
  • PdfTilingBrush:创建大小为 tileWidth × tileHeight 的画刷。当用该画刷绘制一个大的矩形(如整个页面)时,会自动以画刷尺寸为单元进行平铺填充。
  • 水印的透明度SetTransparency(0.3f)设置水印的透明度。范围 0.0 ~ 1.0。
  • 平移与旋转TranslateTransform 将水印绘制原点移动到单元中心,RotateTransform 使水印倾斜,避免完全平铺的单调感。
  • 字体构造new PdfTrueTypeFont("微软雅黑", 24f, PdfFontStyle.Regular, true) 直接使用字体名称、字号、样式和是否嵌入的构造函数,更简洁且支持中文。
  • 页面绘制:对每一页调用 page.Canvas.DrawRectangle,将平铺画刷绘制到整个页面区域,水印即覆盖全页并重复平铺。

三、添加单处局部文本水印

如果只需要在页面某处(如页眉、页脚、角落)添加一个水印,而不是铺满全屏,可以通过直接在页面画布的指定坐标处绘制文本来实现。这种方式更轻量,适合添加版权信息、公司名称、页码等。

using Spire.Pdf;
using Spire.Pdf.Graphics;
using System.Drawing;

namespace TextWatermarkDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            // 加载PDF文档
            PdfDocument pdf = new PdfDocument();
            pdf.LoadFromFile("sample.pdf");

            foreach (PdfPageBase page in pdf.Pages)
            {
                PdfBrush brush = new PdfSolidBrush(Color.FromArgb(60, Color.DarkBlue));
                PdfFont font = new PdfFont(PdfFontFamily.TimesRoman, 22f);
                string waterText = "© 2026 Copyright";

                // 在页面右下角绘制水印,预留边距
                float x = page.ActualSize.Width - 220;
                float y = page.ActualSize.Height - 40;
                page.Canvas.DrawString(waterText, font, brush, x, y);

                // 保存生成带水印的PDF
                pdf.SaveToFile("simple_watermark.pdf");
            }
        }
    }
}

关键参数说明:

  • Color.FromArgb(60, Color.DarkBlue):创建带透明度的颜色。第一个参数 60 为 Alpha 通道(0~255),数值越小越透明。
  • PdfFontFamily.TimesRoman:使用内置 PDF 字体族,无需嵌入字体,文件体积更小。但仅支持英文及基本字符。
  • page.ActualSize.Width/Height:获取页面的实际宽度和高度,用于计算相对位置。
  • page.Canvas.DrawString:在指定 (x, y) 坐标处绘制水印文字。坐标原点为页面左上角。

位置调整技巧

  • 右下角: x = pageWidth - textWidth - margin, y = pageHeight - margin
  • 左下角: x = margin, y = pageHeight - margin
  • 居中x = (pageWidth - textWidth) / 2, y = (pageHeight - textHeight) / 2

如果需要精确测量文字宽度,可以使用 font.MeasureString 方法获取 SizeF 尺寸。

四、实际应用建议与注意事项

4.1 选择合适的水印方式

场景推荐方式
文档密级标识、草稿状态、内部文件(全页背景警示)平铺背景水印
版权声明、公司名称、页码、简单的“Confidential”水印局部单处水印
需要水印倾斜且重复布满整页,但不希望过于遮挡正文平铺背景水印 + 低透明度

4.2 平铺水印的间距与密度调优

  • 单元格尺寸tileWidthtileHeight 建议在 200~400 像素之间。过小会导致文字重叠且绘制性能下降;过大会使水印显得稀疏,失去背景警示作用。
  • 文字字号:平铺水印中的字号通常为 18~28 磅。字号应明显小于单元格尺寸,否则文字会相互挤压。
  • 旋转角度:常用的倾斜角度为 -45° 或 -30°,既美观又不易与正文混淆。

4.3 局部水印的坐标与原点

  • 坐标系原点页面左上角 (0,0),X 向右为正,Y 向下为正。
  • 底部位置:Y 坐标接近 page.ActualSize.Height。例如,放在底部边距 40 磅处,y = pageHeight - 40
  • 顶部位置:Y 坐标较小(如 20 磅)。
  • 绘制文字前,建议先用 MeasureString 获取文字尺寸,避免超出页面边界。

4.4 字体与中文支持

  • 平铺水印:使用 PdfTrueTypeFont("字体名", 字号, 样式, true),最后一个参数 true 表示将字体嵌入 PDF,确保中文在任何设备上正常显示。
  • 局部水印:如果使用 PdfFontFamily 内置字体族(如 TimesRoman, Helvetica),它们不支持中文。若要显示中文,必须同样使用 PdfTrueTypeFont 并嵌入中文字体。
  • 字体名称:在 Windows 系统上,常用中文字体名称为 “微软雅黑”、“宋体”、“黑体” 等。

4.5 常见问题排查

问题现象可能原因与解决方案
水印不显示或极淡透明度设置过低(如 0.1f)。调整为 0.5f 或更高测试。也可能是颜色与背景太接近,换用深色。
平铺水印没有平铺,只显示一个PdfTilingBrush 的尺寸等于或大于页面尺寸。缩小 tileWidth/tileHeight 即可。
局部水印位置错误忘记坐标系原点在左上角,Y 向下为正。顶部用小 Y,底部用大 Y。
中文显示为乱码或方框使用了不包含中文字体的 PdfFontFamily 或未设置字体嵌入。改用 PdfTrueTypeFont 并确保参数 true
保存后水印丢失检查 SaveToFile 之前是否意外关闭了 PdfDocument。确保在绘制循环完成后再保存。

五、总结

本文详细介绍了使用 C# 为 PDF 添加文字水印的两种主流方法:平铺背景水印局部单处水印。两种方法均提供了完整可直接运行的代码示例,并对所有关键参数、中文支持、间距调整等问题给出了详细说明。需要注意的是免费版有 10 页限制,且平铺水印中必须正确设置字体嵌入以支持中文。

在实际开发中,请根据业务需求选择合适的方式,并注意坐标原点与方向、透明度调节和内存管理。希望通过本文,可以快速为自己的 C# 项目集成稳定的 PDF 文字水印功能。

到此这篇关于C# .NET实现为PDF添加平铺背景水印与固定水印的文章就介绍到这了,更多相关C# PDF添加水印内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C# wx获取token的基本方法

    C# wx获取token的基本方法

    这篇文章主要为大家详细介绍了C# wx获取token的基本方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • C#获取硬盘序列号的问题小结

    C#获取硬盘序列号的问题小结

    本文给大家分享C#获取硬盘序列号的问题及解决方法,非常不错,需要的朋友参考下
    2016-12-12
  • vs 中C#项目读取JSON配置文件的方法

    vs 中C#项目读取JSON配置文件的方法

    这篇文章主要介绍了vs中 C#项目读取JSON配置文件的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04
  • 深入C# 内存管理以及优化的方法详解

    深入C# 内存管理以及优化的方法详解

    本篇文章是对C#中内存管理以及优化的方法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C#之return语句的具体使用

    C#之return语句的具体使用

    return是C#中控制方法执行流程和返回值的关键语句,理解其用法对于编写清晰、可维护的代码至关重要,下面就来详细的介绍一下,感兴趣的可以了解一下
    2026-01-01
  • C#开启线程的四种示例

    C#开启线程的四种示例

    这篇文章主要介绍了C#开启线程的四种方法,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下
    2020-10-10
  • C#中HttpClient使用注意(预热与长连接)

    C#中HttpClient使用注意(预热与长连接)

    本文主要介绍了C#中HttpClient使用,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • 一则C#简洁瀑布流代码

    一则C#简洁瀑布流代码

    最近想实现数据的延迟加载,网上找一下有很多例子,看了Masonry的例子启发,自己写了一个很简洁的代码。分享给大家
    2014-06-06
  • 详细分析c# 客户端内存优化

    详细分析c# 客户端内存优化

    这篇文章主要介绍了c# 客户端内存优化的相关资料,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-07-07
  • C#中如何将MongoDB->RunCommand结果映射到业务类的方法总结

    C#中如何将MongoDB->RunCommand结果映射到业务类的方法总结

    这篇文章主要给大家总结介绍了关于C#中如何将MongoDB->RunCommand结果映射到业务类的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
    2018-04-04

最新评论