Python给PDF添加图片水印:Logo铺满每页防篡改
用PyMuPDF把公司Logo或自定义PNG水印批量贴到PDF每页指定位置,支持半透明、平铺、居中,比文字水印更直观,适合合同和报价单外发。
场景痛点
纯文字水印有时不够醒目,客户合同、投标文件外发时,希望每页右下角都贴着公司Logo,或者中央铺一张半透明的底图。手动打开PDF逐页插图,几十页做一遍就够喝一杯咖啡,上百个文件直接放弃。用Python循环insert_image,把Logo按指定坐标贴上去,半透明参数一调,批量搞定。
用到的库
pip install pymupdf pillow
完整代码
# -*- coding: utf-8 -*-
"""
用 PyMuPDF 给 PDF 每页贴一张图片水印(Logo / 半透明底图)。
"""
import fitz # PyMuPDF
from pathlib import Path
from PIL import Image
def make_transparent_watermark(logo_path: str, alpha: int = 80) -> str:
"""把任意图片转成带透明度的 PNG 临时文件,alpha 0~255,越小越透。"""
img = Image.open(logo_path).convert("RGBA")
# 把原图 alpha 通道整体压暗,做出半透明效果
alpha_channel = img.split()[3].point(lambda p: p * alpha // 255)
img.putalpha(alpha_channel)
tmp_path = "_wm_tmp.png"
img.save(tmp_path)
return tmp_path
def add_image_watermark(input_pdf: str,
output_pdf: str,
watermark_png: str,
position: str = "center",
scale: float = 0.3):
"""
position: center / bottom_right / bottom_left
scale: 水印宽度占页面宽度的比例
"""
doc = fitz.open(input_pdf)
for page in doc:
rect = page.rect
# 目标宽度按比例算,高度等比缩放
wm_width = rect.width * scale
# 读图片原始宽高,算等比高度
with Image.open(watermark_png) as im:
w, h = im.size
wm_height = wm_width * h / w
if position == "center":
x0 = (rect.width - wm_width) / 2
y0 = (rect.height - wm_height) / 2
elif position == "bottom_right":
x0 = rect.width - wm_width - 30
y0 = rect.height - wm_height - 30
else: # bottom_left
x0 = 30
y0 = rect.height - wm_height - 30
wm_rect = fitz.Rect(x0, y0, x0 + wm_width, y0 + wm_height)
page.insert_image(wm_rect, filename=watermark_png, overlay=True)
doc.save(output_pdf, garbage=3, deflate=True)
doc.close()
print(f"图片水印完成:{output_pdf}")
def batch_add_image_watermark(input_dir: str,
output_dir: str,
logo_path: str,
position: str = "bottom_right"):
transparent_png = make_transparent_watermark(logo_path, alpha=90)
src, dst = Path(input_dir), Path(output_dir)
dst.mkdir(parents=True, exist_ok=True)
for pdf_file in src.glob("*.pdf"):
add_image_watermark(
str(pdf_file),
str(dst / pdf_file.name),
transparent_png,
position=position,
)
if __name__ == "__main__":
batch_add_image_watermark(
input_dir="originals",
output_dir="watermarked_img",
logo_path="company_logo.png",
position="bottom_right",
)
代码讲解
make_transparent_watermark先用Pillow把Logo转成RGBA,再把alpha通道整体乘一个系数,得到半透明PNG。直接用原图贴上去会太黑,盖住正文。page.insert_image(rect, filename=...)把图片贴到矩形区域,overlay=True表示盖在已有内容上面(水印就该在上面)。- 位置计算:
center就是页面宽高各减水印尺寸除以2;bottom_right贴右下角留30磅边距。 scale=0.3表示水印宽度占页面宽度30%,高度按图片原始比例等比算,不会拉伸变形。- 批量函数把整个文件夹的PDF都处理一遍,输出到新目录,原文件不动。
运行结果
把PDF放进originals/、Logo命名为company_logo.png放在同级目录,跑完后watermarked_img/里每个PDF右下角都贴着半透明的公司Logo,正文清晰可读。
注意事项
- 水印PNG最好本身是透明背景的Logo,用白底图贴上去会有一块白方块盖住正文。
insert_image会把图片数据嵌入PDF,同一张图在多页重复插入时PyMuPDF会自动去重,文件不会膨胀得很厉害。- 想做"整页平铺"的底纹水印,就把scale调大到1.0~1.5,position=center,再把alpha压到50以下。
- 临时文件
_wm_tmp.png跑完可以手动删,或者在脚本最后加Path(transparent_png).unlink()。

更新时间:2026-09-14 21:42:03