pdf-stamp是Linux无图形环境下批量加PDF水印的首选方案,因其纯二进制、无依赖、支持密码PDF及明确错误提示;qpdf+ImageMagick为备选,需分步处理且对PNG水印图尺寸和-density参数有严格要求。

Linux 无图形环境下无法用 GUI 工具(如福昕、星优)批量加 PDF 水印,必须走命令行方案;pdf-stamp 和 qpdf+ImageMagick 是唯二真正可行的离线、无依赖、可脚本化的组合,其他所谓“Python 脚本”在无 X11 的服务器上常因 reportlab 渲染失败或字体缺失直接报错。
为什么不用 PyPDF2 + reportlab?
看似最“标准”,实则在 headless Linux 环境下高频踩坑:
-
reportlab.pdfgen.canvas.Canvas默认依赖系统字体缓存,若未预装fonts-dejavu或未手动指定.ttf路径,会静默回退到位图字体,导致中文乱码或水印不显示 - 生成水印页时需调用
save()写入临时 PDF,但该文件若被并发写入(如 for 循环中未加锁),极易出现PDFSyntaxError: Invalid PDF header - PyPDF2 的
mergePage()对加密 PDF 兼容性差,遇到带 owner password 的文件直接抛NotImplementedError,且不提示原因
推荐方案:pdf-stamp 命令行工具
pdf-stamp 是专为服务端设计的轻量工具,纯二进制,无 Python/Java 运行时依赖,支持文字/图片水印、透明度、角度、平铺,且对密码保护 PDF 有明确错误提示。
安装与使用:
- 下载静态二进制:
wget https://github.com/junegunn/pdf-stamp/releases/download/v0.4.0/pdf-stamp_0.4.0_linux_amd64.tar.gz - 解压并赋予执行权限:
tar -xzf pdf-stamp_0.4.0_linux_amd64.tar.gz && chmod +x pdf-stamp - 添加文字水印(45°倾斜、30%透明、居中平铺):
./pdf-stamp -t "CONFIDENTIAL" -a 45 -o 0.3 -p "all" input.pdf -o output.pdf - 批量处理所有 PDF:
for f in *.pdf; do ./pdf-stamp -t "INTERNAL" -a 40 -o 0.35 -p "all" "$f" -o "${f%.pdf}_watermarked.pdf"; done
注意:-p "all" 必须显式指定,否则默认只处理第一页;-o 0.35 中的 0.35 是浮点值,不能写成 35%,否则解析失败。
备选方案:qpdf + ImageMagick 组合(需额外步骤)
当 pdf-stamp 不适用(如需自定义 PNG 水印图),可用此链式流程,但必须分三步走,不可合并为单条命令:
- 先用
qpdf拆出每页为独立 PDF:qpdf --split-pages input.pdf split/ - 用
convert将每页转为 PNG,叠加水印图,再转回 PDF:convert page-0001.pdf -gravity center -density 150 watermark.png -composite -quality 90 page-0001_watermarked.pdf - 最后用
pdfunite合并:pdfunite split/page-*-watermarked.pdf output.pdf
关键限制:convert 处理 PDF 页时必须加 -density 150,否则文字边缘严重锯齿;watermark.png 必须是透明背景、尺寸 ≥ A4 像素(如 2480×3508),否则平铺后留白或拉伸变形。
真正容易被忽略的是 PDF 加密状态——无论用哪种命令行工具,只要源文件带 owner password,就必须先用 qpdf --decrypt input.pdf decrypted.pdf 解密,否则所有工具都静默跳过或报错退出,不会主动提示“文件被加密”。



















