C# .NET实现为PDF添加平铺背景水印与固定水印
作者:咕白m625
在 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 提供的平铺画刷工具。通过设置平铺单元尺寸(tileWidth 和 tileHeight),可以让水印在页面上重复平铺,形成网格状或阵列状的水印背景。这种方式非常适合制作「文件密级」「内部资料」等背景水印效果。
以下是完整的平铺水印实现代码:
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");
}
}
}
}
代码说明:
tileWidth和tileHeight决定了每个水印单元的大小,也就是水印重复排列的间距。实际生成时,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 平铺水印的间距与密度调优
- 单元格尺寸:
tileWidth和tileHeight建议在 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添加水印内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
