批量添加水印并调整位置脚本

wen 实用脚本 1

本文目录导读:

批量添加水印并调整位置脚本

  1. 使用方法
  2. 脚本特性
  3. 注意事项
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
批量图片水印添加脚本
功能:为指定文件夹内所有图片添加文字水印,并支持灵活调整水印位置
依赖:Pillow (pip install Pillow)
"""
import os
import argparse
from PIL import Image, ImageDraw, ImageFont
# 水印位置预设
POSITIONS = {
    '左上': (0.05, 0.05),
    '右上': (0.85, 0.05),
    '左下': (0.05, 0.85),
    '右下': (0.85, 0.85),
    '居中': (0.40, 0.45),
}
def get_font(size, font_path=None):
    """加载字体,若未提供则使用默认字体"""
    try:
        if font_path and os.path.exists(font_path):
            return ImageFont.truetype(font_path, size)
        # 尝试加载常见中文字体,否则用默认
        for candidate in [
            "msyh.ttc", "simhei.ttf", "arial.ttf",
            "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"
        ]:
            try:
                return ImageFont.truetype(candidate, size)
            except:
                continue
        return ImageFont.load_default()
    except:
        return ImageFont.load_default()
def add_watermark(input_path, output_path, text, position='右下', 
                  font_size=24, opacity=128, font_path=None, 
                  margin=10, angle=0):
    """
    为单张图片添加水印
    参数:
        input_path: 输入图片路径
        output_path: 输出图片路径
        text: 水印文字内容
        position: 水印位置(左上/右上/左下/右下/居中,或自定义坐标元组)
        font_size: 字体大小
        opacity: 透明度 (0-255)
        font_path: 字体文件路径(可选)
        margin: 边距(像素)
        angle: 水印旋转角度(度)
    """
    try:
        # 打开图片并转换为RGBA模式以支持透明
        image = Image.open(input_path).convert('RGBA')
        img_width, img_height = image.size
        # 创建透明水印层
        watermark = Image.new('RGBA', image.size, (0, 0, 0, 0))
        draw = ImageDraw.Draw(watermark)
        # 获取字体
        font = get_font(font_size, font_path)
        # 计算文字尺寸
        try:
            bbox = draw.textbbox((0, 0), text, font=font)
            text_width = bbox[2] - bbox[0]
            text_height = bbox[3] - bbox[1]
        except:
            text_width, text_height = draw.textsize(text, font=font)
        # 确定水印位置
        if isinstance(position, tuple):
            # 自定义坐标(相对位置 0-1)
            x = int((img_width - text_width) * position[0])
            y = int((img_height - text_height) * position[1])
        elif position in POSITIONS:
            # 预设位置
            rel_x, rel_y = POSITIONS[position]
            # 预设位置默认带边距
            x = int((img_width - text_width) * rel_x)
            y = int((img_height - text_height) * rel_y)
        else:
            raise ValueError(f"未知位置: {position}")
        # 应用边距
        x = max(0, min(x + margin, img_width - text_width - margin))
        y = max(0, min(y + margin, img_height - text_height - margin))
        # 添加文字到水印层
        draw.text((x, y), text, font=font, fill=(255, 255, 255, opacity))
        # 如果需要旋转
        if angle != 0:
            watermark = watermark.rotate(angle, resample=Image.BICUBIC, 
                                         center=(x + text_width//2, y + text_height//2))
        # 合并原图和水印
        result = Image.alpha_composite(image, watermark)
        # 转换为RGB模式保存(去除alpha通道)
        if output_path.lower().endswith('.jpg') or output_path.lower().endswith('.jpeg'):
            result = result.convert('RGB')
        result.save(output_path)
        print(f"✅ 已处理: {os.path.basename(input_path)} -> {output_path}")
        return True
    except Exception as e:
        print(f"❌ 处理失败 {os.path.basename(input_path)}: {str(e)}")
        return False
def batch_watermark(input_dir, output_dir, text, **kwargs):
    """批量处理指定目录下的所有图片"""
    # 支持的图片格式
    img_extensions = {'.jpg', '.jpeg', '.png', '.bmp', '.gif', '.tiff'}
    # 创建输出目录
    os.makedirs(output_dir, exist_ok=True)
    # 收集所有图片文件
    img_files = [f for f in os.listdir(input_dir) 
                 if os.path.splitext(f)[1].lower() in img_extensions]
    if not img_files:
        print("⚠️  未找到任何图片文件")
        return
    print(f"📁 找到 {len(img_files)} 张图片,开始处理...")
    success_count = 0
    for filename in sorted(img_files):
        input_path = os.path.join(input_dir, filename)
        # 保持原文件名,但更改扩展号为.png(支持透明)
        output_filename = os.path.splitext(filename)[0] + '_watermarked.png'
        output_path = os.path.join(output_dir, output_filename)
        if add_watermark(input_path, output_path, text, **kwargs):
            success_count += 1
    print(f"\n🎉 处理完成!成功: {success_count}/{len(img_files)} 张图片")
    print(f"📂 输出目录: {os.path.abspath(output_dir)}")
def main():
    parser = argparse.ArgumentParser(description='批量图片水印添加工具')
    parser.add_argument('input_dir', help='输入图片目录路径')
    parser.add_argument('output_dir', help='输出图片目录路径')
    parser.add_argument('--text', required=True, help='水印文字内容')
    parser.add_argument('--position', default='右下', 
                        choices=list(POSITIONS.keys()),
                        help='水印位置:左上/右上/左下/右下/居中 (默认: 右下)')
    parser.add_argument('--font-size', type=int, default=24, help='字体大小 (默认: 24)')
    parser.add_argument('--opacity', type=int, default=128, 
                        help='透明度 0-255 (默认: 128)')
    parser.add_argument('--font-path', help='字体文件路径(可选)')
    parser.add_argument('--margin', type=int, default=10, help='边距像素 (默认: 10)')
    parser.add_argument('--angle', type=float, default=0, help='旋转角度(度)')
    args = parser.parse_args()
    # 参数校验
    if not 0 <= args.opacity <= 255:
        print("⚠️  透明度必须在 0-255 之间,已自动处理")
        args.opacity = max(0, min(255, args.opacity))
    batch_watermark(
        args.input_dir,
        args.output_dir,
        args.text,
        position=args.position,
        font_size=args.font_size,
        opacity=args.opacity,
        font_path=args.font_path,
        margin=args.margin,
        angle=args.angle
    )
if __name__ == '__main__':
    main()

使用方法

安装依赖

pip install Pillow

命令行用法示例

# 基本用法(默认右下角水印)
python watermark.py ./input_images ./output_images --text "© 我的水印"
# 指定位置为居中
python watermark.py ./input_images ./output_images --text "机密" --position 居中
# 自定义字体大小和透明度
python watermark.py ./input ./output --text "保密" --position 右上 --font-size 36 --opacity 150
# 使用指定字体文件
python watermark.py ./input ./output --text "设计师" --position 左下 --font-path "C:/Windows/Fonts/msyh.ttc"
# 添加旋转效果
python watermark.py ./input ./output --text "预览版" --position 居中 --angle 30

在Python代码中调用

from watermark import batch_watermark
# 批量处理
batch_watermark(
    input_dir="photos",
    output_dir="watermarked",
    text="© 2024",
    position="右下",
    font_size=30,
    opacity=150,
    margin=15
)

脚本特性

  • 多位置预设:支持左上、右上、左下、右下、居中五种常用位置
  • 自定义坐标:可传入精确的相对坐标 (0~1之间的浮点数)
  • 参数丰富:可调节字体大小、透明度、边距和旋转角度
  • 自动编码处理:自动读取图片并保持格式,输出为PNG以支持透明
  • 批量处理:自动遍历目录内所有常见图片格式
  • 错误处理:单个文件失败不影响其他文件处理

注意事项

  1. 输出的图片格式统一为PNG,以支持高质量的透明效果
  2. 若需要保持原始格式(如JPG),可以修改脚本中的保存部分代码
  3. 中文水印需要系统有中文字体支持,否则会显示方块
  4. 建议先在小规模测试,确认效果后再批量处理

如果您需要调整水印样式(如添加阴影、边框等),可以告诉我,我可以进一步扩展脚本功能。

抱歉,评论功能暂时关闭!