PDF 加水印
文字水印 · 自定义字体颜色透明度角度 · 浏览器本地处理
文字/图片/平铺
文字水印 · 自定义字体颜色透明度角度 · 浏览器本地处理
商业机密:"机密"/"CONFIDENTIAL" - 内部分发文档
草稿标识:"DRAFT"/"草稿" - 未定稿版本
版权保护:公司名 + 日期 - 防止盗用
追溯标识:阅读者姓名 + 日期 - 追踪泄露源
了解工具定位 · 使用场景 · 对比优势
给 PDF 文档添加文字或图片水印,支持平铺排列,防止文件被未经授权使用。适合需要保护合同、设计稿、报告版权的个人或企业,或给内部文档标注“草稿”“仅供预览”等状态。上传 PDF 后选择水印内容、位置和透明度,后端处理完成后即可下载。文件仅用于临时处理,不会长期留存。
法务或行政人员在发送电子合同时,担心对方修改条款或金额。使用本工具将合同 PDF 加上包含公司 Logo 的图片水印,平铺覆盖全文。水印在页面上的固定位置不可编辑,接收方无法在不破坏文档的情况下删除或覆盖,有效降低合同被篡改的风险。
高校学生或研究人员在提交论文、设计作品或作业时,担心被他人冒用或抄袭。将 PDF 文件添加包含学号、姓名或作品标题的文字水印,平铺于每一页。即使截图或复印,水印信息依然可见,能清晰追溯来源,保护原创成果。
企业 HR 或部门主管向员工分发员工手册、制度文件等内部 PDF 时,担心文件被外传。在文件上添加包含员工工号或部门名称的文字水印,平铺于页面。一旦文件泄露,可根据水印信息快速定位到具体责任人,实现分发可追溯。
摄影师或设计师在向客户发送样片集 PDF 时,担心高清图片被直接保存商用。将包含个人 Logo 或网站域名的图片水印以低透明度平铺在图片上,既不影响客户预览效果,又使盗图者无法直接使用无水印原图,保护作品版权。
财务人员在向审计或股东发送季度财报 PDF 时,需要确保文件在传输过程中不被截取后冒用。在财报每一页添加包含“仅供内部审计”或“机密”字样的文字水印,平铺覆盖。即使文件被转发,水印也明确标识了文件的保密性质与用途。
| 维度 | 本工具 | iLovePDF | Adobe Acrobat Pro |
|---|---|---|---|
| 数据隐私 | 纯浏览器处理,文件不上传服务器 | 文件上传至云服务器处理 | 本地处理,但需安装桌面软件 |
| 处理速度 | 1-3 秒(取决于文件大小) | 5-15 秒(含上传/下载时间) | 1-5 秒(本地处理) |
| 离线可用 | 支持(页面加载后完全离线) | 不支持(必须联网) | 支持(安装后离线使用) |
| 收费模式 | 完全免费,无水印 | 基础免费,高级功能付费 | 付费订阅(约 ¥150/月) |
| 注册要求 | 无需注册,打开即用 | 免费用户有限制,需注册 | 需注册 Adobe 账号 |
| 水印类型 | 文字、图片、平铺 | 文字、图片、平铺、PDF 覆盖 | 文字、图片、动态字段、页码 |
| 文件大小限制 | 无限制(浏览器内存决定) | 免费版 100MB,付费版 2GB | 无限制 |
上手步骤 · 输入输出 · 避坑提示
| 输入 | 输出 | 说明 |
|---|---|---|
| 上传一个 3 页的合同 PDF,选择文字水印「机密」,透明度 50%,旋转 45 度,平铺 | 生成一个 3 页的合同 PDF,每页背景平铺「机密」文字水印,倾斜 45 度,半透明可见 | 典型场景:商业文件标注保密级别 |
| 上传一张 JPG 图片(公司 Logo),选择图片水印,不透明度 30%,平铺在 PDF 第一页 | PDF 第一页背景平铺 Logo 图片水印,其余页面无水印 | 典型场景:仅对特定页面添加品牌标识 |
| 上传一个 200 页的 PDF,选择文字水印「草稿」,平铺,不透明度 100% | 生成 200 页 PDF,每页被「草稿」文字完全覆盖,背景不可见 | 边界 case:大文件 + 完全不透明水印 |
| 上传一个 1 页的空白 PDF,选择文字水印「测试」,字号 1pt,不透明度 1% | 水印极小且几乎透明,肉眼难以辨认 | 边界 case:极端小字号与低透明度组合 |
| 上传一个加密的 PDF(需密码打开),选择文字水印「样本」 | 工具提示「文件已加密,请先解密后再添加水印」 | 易错 case:加密文件无法直接处理 |
| 上传一个扫描件 PDF(图片形式,无文字层),选择文字水印「仅供预览」 | 水印成功添加在扫描件图片上方,不影响原图内容 | 易错 case:扫描件同样支持文字水印 |
水印文字:© 2024 公司™ 文件水印文字:2024 公司 文件©/™/® 等符号在 PDF 字体子集中可能缺失,导致渲染为方块或乱码;后端 Go 默认字体不含这些符号的嵌入
水印文字:这是一份非常非常非常非常非常非常非常非常非常非常非常长的水印文字(超过 200 字)水印文字:机密文件后端处理时单行文字超过 200 字会导致 PDF 排版引擎内存溢出,服务端返回 502;建议控制在 50 字以内
上传一个从微信下载的、提示“请输入密码”的 PDF先使用密码移除工具解密,再上传后端 Go 无法处理加密 PDF(PDF 1.7 标准加密流),会直接返回“文件解析失败”;需先解密
透明度:0.05透明度:0.3透明度值范围 0-1,低于 0.1 时肉眼几乎不可见;后端渲染时 alpha 通道会截断到整数,0.05 实际等于 0
旋转角度:45 度,水印文字:机密文件机密文件机密文件旋转角度:0 度,水印文字:机密文件45 度旋转后文字对角线长度增加约 1.4 倍,长文字会超出页面边界被裁切;建议 0 度或 90 度
平铺间距:5px平铺间距:50px间距小于 10px 时水印会重叠成一片,视觉上变成纯色块,失去水印作用;后端按像素计算间距,重叠后无法区分
上传一个包含可填写表单(AcroForm)的 PDF,直接加水印先使用“扁平化表单”工具处理,再加水印表单字段的坐标系统与页面内容不同,水印会定位到表单字段的偏移位置;后端 Go 不处理 AcroForm 坐标变换
颜色:#FF00FF00(四通道)或 RGB(300, 0, 0)颜色:#FF0000 或 RGB(255, 0, 0)PDF 颜色空间仅支持 0-255 的 8 位 RGB;超范围值后端会截断,但用户可能误以为支持 RGBA 或 HSL
公式推导 · 流程图解 · 依据出处
W(x, y) = α · T(x, y) + β · I(x, y)
W(x, y) — 像素 (x, y) 处最终颜色值T(x, y) — 水印图案在 (x, y) 处的颜色值I(x, y) — 原始 PDF 页面在 (x, y) 处的颜色值α — 水印透明度系数(0~1)β — 原始内容保留系数(通常 β = 1 - α)将半透明红色水印(RGB=255,0,0)以 α=0.3 叠加到白色 PDF 页面(RGB=255,255,255)上。对于像素 (100,200):T=255,0,0;I=255,255,255;α=0.3,β=0.7。R 通道 = 0.3×255 + 0.7×255 = 255;G 通道 = 0.3×0 + 0.7×255 = 178.5 → 179;B 通道 = 0.3×0 + 0.7×255 = 179。最终像素颜色为 (255, 179, 179),即浅粉色。
适用于所有基于像素混合的图片/文字水印叠加场景。不适用于矢量水印(如 PDF 原生注释)或加密水印(需频域变换)。公式为计算机图形学标准 Alpha 混合算法(Porter & Duff, 1984)。
3 种主流语言 · 复制即用
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
from reportlab.lib.units import inch
import io
# 生成一个示例 PDF 并添加文字水印
def add_text_watermark(input_pdf_path, output_pdf_path, watermark_text="CONFIDENTIAL"):
# 创建水印层
packet = io.BytesIO()
c = canvas.Canvas(packet, pagesize=letter)
c.setFont("Helvetica", 60)
c.setFillAlpha(0.2) # 透明度
c.saveState()
c.translate(letter[0]/2, letter[1]/2)
c.rotate(45)
c.drawCentredString(0, 0, watermark_text)
c.restoreState()
c.save()
packet.seek(0)
# 合并到原 PDF
from PyPDF2 import PdfReader, PdfWriter
reader = PdfReader(input_pdf_path)
watermark = PdfReader(packet)
writer = PdfWriter()
for page in reader.pages:
page.merge_page(watermark.pages[0])
writer.add_page(page)
with open(output_pdf_path, "wb") as f:
writer.write(f)
# 使用示例(假设已有 input.pdf)
# add_text_watermark("input.pdf", "output.pdf", "SAMPLE")package main
import (
"github.com/unidoc/unipdf/v3/common/license"
"github.com/unidoc/unipdf/v3/creator"
"github.com/unidoc/unipdf/v3/model"
"log"
)
func addWatermark(inputPath, outputPath, text string) {
// 初始化许可证(生产环境需设置有效 key)
license.SetMeteredKey("")
// 读取源 PDF
reader, err := model.NewPdfReaderFromFile(inputPath, nil)
if err != nil {
log.Fatal(err)
}
// 创建新 PDF
c := creator.New()
numPages, _ := reader.GetNumPages()
for i := 1; i <= numPages; i++ {
page, _ := reader.GetPage(i)
c.AddPage(page)
// 添加水印
wm := c.NewText(text)
wm.SetFontSize(48)
wm.SetColor(creator.ColorRGBFromHex("#cccccc"))
wm.SetOpacity(0.3)
wm.SetAngle(45)
wm.SetPos(200, 400)
c.Draw(wm)
}
c.WriteToFile(outputPath)
}
func main() {
addWatermark("input.pdf", "output.pdf", "DRAFT")
}const { PDFDocument, rgb, degrees } = require('pdf-lib');
const fs = require('fs');
async function addWatermark(inputPath, outputPath, text = 'WATERMARK') {
const pdfDoc = await PDFDocument.load(fs.readFileSync(inputPath));
const pages = pdfDoc.getPages();
pages.forEach((page) => {
const { width, height } = page.getSize();
page.drawText(text, {
x: width / 2 - 100,
y: height / 2,
size: 50,
opacity: 0.2,
rotate: degrees(-45),
color: rgb(0.8, 0.8, 0.8),
});
});
const pdfBytes = await pdfDoc.save();
fs.writeFileSync(outputPath, pdfBytes);
}
// 使用示例
// addWatermark('input.pdf', 'output.pdf', 'CONFIDENTIAL');7 个高频疑问