C# PDF文件添加水印 C#如何给现有的PDF文档加上文字或图片水印

来源:这里教程网 时间:2026-02-21 17:43:12 作者:

用 iTextSharp 添加文字水印时,
PageStamp
ContentByte
的调用时机很关键

直接在

OnEndPage
里写水印,但没调用
cb.SaveState()
cb.RestoreState()
,会导致后续内容(比如页眉页脚)被旋转或透明度污染。文字水印必须在页面内容绘制前叠加,且需独立坐标系。

先调用
cb.SaveState()
,再设置旋转、字体、颜色、透明度
cb.BeginText()
+
cb.ShowTextAligned()
写文字,别用
ColumnText
文字位置建议用
document.PageSize.Width / 2
document.PageSize.Height / 2
居中,再手动平移避免裁剪
如果水印文字被原PDF内容盖住,说明你写在了
DirectContent
而不是
DirectContentUnder

iTextSharp v5 中图片水印必须预加载为
PdfTemplate
Jpeg
对象

不能直接传文件路径字符串给

cb.AddImage()
;否则会抛出
NullReferenceException
或静默失败。图片尺寸、DPI、色彩模式也会影响渲染效果——常见问题是 PNG 透明通道丢失或 JPG 拉伸变形。

Jpeg.GetInstance(imagePath)
加载 JPG,
Png.GetInstance(imagePath)
加载 PNG(注意后者需启用 alpha 支持)
缩放图片推荐用
img.ScaleAbsolute(200f, 100f)
,别依赖原始尺寸;太大易撑破页面,太小看不清
叠加前务必调用
img.SetAbsolutePosition(x, y)
,x/y 是左下角坐标,不是中心点
若 PDF 原始页面是 A4 但旋转了(如 landscape),要先读
page.PageSize.Rotate
再算坐标

替换现有 PDF 时,
PdfStamper
的构造参数决定水印是否可编辑

new PdfStamper(reader, output, '<p>用 <code>new PdfStamper(reader, output, '\0', true)
的第四个参数设为
true
,才能启用“提升权限”模式,否则添加的水印图层可能被 Acrobat 识别为普通内容而允许删除。但这也意味着输出 PDF 会带修改密码保护标记(即使没设密码),部分下游系统会报“文档已加密”警告。

', true) 的第四个参数设为
true
,才能启用“提升权限”模式,否则添加的水印图层可能被 Acrobat 识别为普通内容而允许删除。但这也意味着输出 PDF 会带修改密码保护标记(即使没设密码),部分下游系统会报“文档已加密”警告。

不加权限提升:水印能被轻易删掉,适合内部草稿 加权限提升:水印图层锁定,但需确认接收方 PDF 阅读器兼容性(尤其国产阅读器常忽略该标志)
PdfStamper.FormFlattening = true
可防止表单域遮挡水印,但会丢弃所有交互能力

.NET Core 项目里引用 iTextSharp 会遇到签名冲突和 GDI+ 依赖问题

iTextSharp v5.5.x 不支持 .NET Standard,强行 NuGet 安装后编译通过,运行时却在

PdfContentByte.ShowTextAligned()
System.TypeInitializationException
—— 根源是其内部用了
System.Drawing.Common
,而 .NET Core 3.1+ 默认不启用 GDI+。

方案一:降级用 iText7(
iText7.PdfCore
),API 完全重写,但支持 .NET 6+,水印用
Canvas
+
Div
构建
方案二:保留 iTextSharp,项目文件加
<usewpf>true</usewpf>
<usewindowsforms>true</usewindowsforms>
方案三:改用
QuestPDF
生成带水印的新 PDF,而非修改旧文件——适合水印内容固定、无需保留原文档结构的场景

真正麻烦的不是加水印这一步,而是判断原 PDF 是否含加密、是否有 XFA 表单、是否用了非标准字体嵌入——这些都会让水印位置偏移或文字乱码。动手前先用

PdfReader.IsEncrypted
reader.Catalog.GetAsDict(PdfName.ACROFORM)
探查文档元信息。

相关推荐

热文推荐