我的知识记录

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()

Python给PDF添加图片水印:Logo铺满每页防篡改

标签:

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

上一篇:Python批量给PDF添加页码 底部居中教程

下一篇:Python Word批量转纯文本txt:提取正文