Python 批量给图片加水印:文字水印和图片水印两种方案
用 Python Pillow 给整目录图片批量加文字水印或 Logo 水印,支持透明度、位置、字号自适应,防盗图脚本一键跑完,附完整代码。
场景痛点
自己拍的图、设计的稿,发到网上总被盗。用美图秀秀一张一张加 Logo 文字,几十张图要点几十次,位置还对不齐。用 Python 脚本跑一遍,所有图片统一在右下角加半透明文字水印,或者把公司 Logo 贴到左下角,位置、字号、透明度全部代码里控制,可重复执行。
用到的库
pip install Pillow
完整代码
import os
from PIL import Image, ImageDraw, ImageFont
SRC_EXTS = (".jpg", ".jpeg", ".png", ".webp")
def add_text_watermark(img, text="© 2026 MySite", font_size_ratio=0.04):
"""给图片加半透明文字水印,放在右下角"""
img = img.convert("RGBA")
overlay = Image.new("RGBA", img.size, (0, 0, 0, 0))
draw = ImageDraw.Draw(overlay)
# 字号按图片宽度自适应,避免小图水印太大、大图水印太小
font_size = max(12, int(img.width * font_size_ratio))
try:
# Windows 用 msyh.ttc,Mac 用 Arial.ttf,按需替换
font = ImageFont.truetype("msyh.ttc", font_size)
except OSError:
font = ImageFont.load_default()
# 计算文字尺寸,贴到右下角留边距
bbox = draw.textbbox((0, 0), text, font=font)
tw, th = bbox[2] - bbox[0], bbox[3] - bbox[1]
margin = int(img.width * 0.02)
x = img.width - tw - margin
y = img.height - th - margin
# 半透明白色,第四个参数是透明度 0-255
draw.text((x, y), text, font=font, fill=(255, 255, 255, 128))
return Image.alpha_composite(img, overlay).convert("RGB")
def add_logo_watermark(img, logo_path, ratio=0.15):
"""把 logo 图片贴到左下角,logo 宽度按原图比例缩放"""
img = img.convert("RGBA")
logo = Image.open(logo_path).convert("RGBA")
new_w = int(img.width * ratio)
new_h = int(logo.height * new_w / logo.width)
logo = logo.resize((new_w, new_h), Image.LANCZOS)
overlay = Image.new("RGBA", img.size, (0, 0, 0, 0))
margin = int(img.width * 0.02)
overlay.paste(logo, (margin, img.height - new_h - margin), logo)
return Image.alpha_composite(img, overlay).convert("RGB")
def batch_watermark(src_dir, dst_dir, mode="text", text="© 2026 MySite", logo_path=None):
"""批量给目录下图片加水印,mode 选 text 或 logo"""
os.makedirs(dst_dir, exist_ok=True)
for root, _, files in os.walk(src_dir):
for name in files:
if not name.lower().endswith(SRC_EXTS):
continue
src_path = os.path.join(root, name)
rel = os.path.relpath(src_path, src_dir)
dst_path = os.path.join(dst_dir, rel)
os.makedirs(os.path.dirname(dst_path), exist_ok=True)
try:
with Image.open(src_path) as img:
if mode == "text":
out = add_text_watermark(img, text)
else:
out = add_logo_watermark(img, logo_path)
out.save(dst_path, "JPEG", quality=92)
print(f"已加水印:{src_path}")
except Exception as e:
print(f"失败:{src_path},原因:{e}")
def main():
# 文字水印模式
batch_watermark("./photos", "./photos_wm", mode="text", text="© 2026 我的版权")
# 图片 logo 水印模式,把 logo.png 换成自己的
# batch_watermark("./photos", "./photos_logo", mode="logo", logo_path="./logo.png")
if __name__ == "__main__":
main()
代码讲解
- 水印的核心是先建一张和原图一样大的透明图层
overlay,在上面画文字或贴 Logo,再用alpha_composite合成到原图上。这样水印的透明度能单独控制,不破坏原图像素。 - 文字颜色
(255,255,255,128)第四个值是 alpha 透明度,128 就是 50% 透明。 - 字号按图片宽度比例算,大图用大字号、小图用小字号,不会出现水印盖住整张图的尴尬情况。
textbbox算出文字实际宽高,才能把水印精确贴到右下角。- Logo 模式下
paste第三个参数传 logo 自身作为 mask,PNG 透明背景才不会变成方块。
运行结果
运行后在 ./photos_wm 下生成加完水印的 JPEG 图片,右下角有半透明白色版权文字。换成 logo 模式后左下角会出现公司 Logo,所有图位置完全一致。
注意事项
msyh.ttc是 Windows 微软雅黑字体,Mac 下换成/System/Library/Fonts/PingFang.ttc,Linux 下先sudo apt install fonts-wqy-zenhei再指定字体路径。- 字体文件找不到会自动 fallback 到默认位图字体,中文可能显示成方块,一定要改成本机存在的字体路径。
- 水印别加在画面正中央,影响观感又挡主体;右下角或左下角加边距最稳。
- 原图不动,输出到新目录,跑错了直接删输出目录重来。

更新时间:2026-09-14 20:43:57
上一篇:Python 批量生成缩略图:网站列表页快速预览图教程