批量添加日期水印的脚本

wen 实用脚本 2

本文目录导读:

批量添加日期水印的脚本

  1. Python脚本(支持图片)
  2. 安装依赖
  3. 使用示例
  4. 视频水印脚本(可选)
  5. 使用说明

我来为您提供一个批量添加日期水印的Python脚本,支持图片和视频文件。

Python脚本(支持图片)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
批量添加日期水印脚本
支持格式:JPG, PNG, BMP, TIFF等图片格式
"""
import os
import sys
from datetime import datetime
from PIL import Image, ImageDraw, ImageFont
import argparse
def add_date_watermark(image_path, output_path, watermark_text, position='bottom_right', 
                      font_size=30, opacity=128, font_path=None):
    """
    在图片上添加日期水印
    参数:
        image_path: 输入图片路径
        output_path: 输出图片路径
        watermark_text: 水印文本
        position: 水印位置 (top_left, top_right, bottom_left, bottom_right)
        font_size: 字体大小
        opacity: 不透明度 (0-255)
        font_path: 字体文件路径 (None使用默认字体)
    """
    try:
        # 打开图片
        img = Image.open(image_path)
        if img.mode != 'RGBA':
            img = img.convert('RGBA')
        # 创建透明图层用于水印
        watermark = Image.new('RGBA', img.size, (0, 0, 0, 0))
        draw = ImageDraw.Draw(watermark)
        # 设置字体
        try:
            if font_path:
                font = ImageFont.truetype(font_path, font_size)
            else:
                # 使用系统默认字体(尝试多个)
                try:
                    font = ImageFont.truetype("arial.ttf", font_size)
                except:
                    try:
                        font = ImageFont.truetype("simhei.ttf", font_size)  # 中文字体
                    except:
                        font = ImageFont.load_default()  # 最后使用默认字体
        except:
            font = ImageFont.load_default()
        # 计算水印位置
        text_width = draw.textlength(watermark_text, font=font)
        text_height = font_size
        # 获取图片尺寸
        img_width, img_height = img.size
        # 设置边距
        margin = 20
        # 计算位置坐标
        if position == 'top_left':
            x, y = margin, margin
        elif position == 'top_right':
            x, y = img_width - text_width - margin, margin
        elif position == 'bottom_left':
            x, y = margin, img_height - text_height - margin
        elif position == 'bottom_right':
            x, y = img_width - text_width - margin, img_height - text_height - margin
        elif position == 'center':
            x, y = (img_width - text_width) // 2, (img_height - text_height) // 2
        else:  # 默认bottom_right
            x, y = img_width - text_width - margin, img_height - text_height - margin
        # 添加水印
        draw.text((x, y), watermark_text, font=font, fill=(255, 255, 255, opacity))
        # 合并图片和水印
        result = Image.alpha_composite(img, watermark)
        # 保存图片
        if result.mode == 'RGBA':
            # 对于JPG格式需要转换
            if output_path.lower().endswith(('.jpg', '.jpeg')):
                result = result.convert('RGB')
        result.save(output_path, quality=95)
        print(f"✓ 已处理: {os.path.basename(image_path)}")
        return True
    except Exception as e:
        print(f"✗ 处理失败 {image_path}: {str(e)}")
        return False
def process_images(input_dir, output_dir, watermark_text, position='bottom_right', 
                  font_size=30, opacity=128, recursive=False):
    """
    批量处理图片
    参数:
        input_dir: 输入目录
        output_dir: 输出目录
        watermark_text: 水印文本
        position: 水印位置
        font_size: 字体大小
        opacity: 不透明度
        recursive: 是否递归子目录
    """
    # 支持的图片格式
    supported_formats = ['.jpg', '.jpeg', '.png', '.bmp', '.tiff', '.tif', '.webp']
    # 创建输出目录
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)
    # 扫描文件
    file_count = 0
    success_count = 0
    for root, dirs, files in os.walk(input_dir):
        if not recursive and root != input_dir:
            continue
        for filename in files:
            ext = os.path.splitext(filename)[1].lower()
            if ext in supported_formats:
                file_count += 1
                input_path = os.path.join(root, filename)
                # 保持目录结构
                rel_path = os.path.relpath(root, input_dir)
                if rel_path == '.':
                    output_subdir = output_dir
                else:
                    output_subdir = os.path.join(output_dir, rel_path)
                    if not os.path.exists(output_subdir):
                        os.makedirs(output_subdir)
                # 生成输出路径
                output_path = os.path.join(output_subdir, filename)
                # 处理图片
                if add_date_watermark(input_path, output_path, watermark_text, 
                                    position, font_size, opacity):
                    success_count += 1
    print(f"\n处理完成!")
    print(f"总共扫描: {file_count} 个文件")
    print(f"成功处理: {success_count} 个文件")
    print(f"输出目录: {output_dir}")
def main():
    parser = argparse.ArgumentParser(description='批量添加日期水印脚本')
    parser.add_argument('input_dir', help='输入图片目录')
    parser.add_argument('output_dir', nargs='?', default='output', help='输出目录(默认: output)')
    parser.add_argument('--date', default=None, help='自定义日期文本(默认使用当前日期)')
    parser.add_argument('--format', default='%Y-%m-%d', help='日期格式(默认: YYYY-MM-DD)')
    parser.add_argument('--position', default='bottom_right', 
                       choices=['top_left', 'top_right', 'bottom_left', 'bottom_right', 'center'],
                       help='水印位置')
    parser.add_argument('--font-size', type=int, default=30, help='字体大小')
    parser.add_argument('--opacity', type=int, default=128, help='不透明度 (0-255)')
    parser.add_argument('--recursive', action='store_true', help='递归子目录')
    parser.add_argument('--font-path', default=None, help='自定义字体路径')
    args = parser.parse_args()
    # 检查输入目录
    if not os.path.exists(args.input_dir):
        print(f"错误: 输入目录不存在: {args.input_dir}")
        sys.exit(1)
    # 确定水印文本
    if args.date:
        watermark_text = args.date
    else:
        watermark_text = datetime.now().strftime(args.format)
    print(f"水印文本: {watermark_text}")
    print(f"处理目录: {args.input_dir}")
    print(f"输出目录: {args.output_dir}")
    print("-" * 50)
    # 处理图片
    process_images(args.input_dir, args.output_dir, watermark_text,
                  args.position, args.font_size, args.opacity, args.recursive)
if __name__ == "__main__":
    main()

安装依赖

pip install pillow

使用示例

# 基本用法(使用当前日期)
python watermark.py /path/to/images /path/to/output
# 自定义日期
python watermark.py /path/to/images /path/to/output --date "2024-01-15"
# 自定义日期格式(如:2024年1月15日)
python watermark.py /path/to/images /path/to/output --format "%Y年%m月%d日"
# 自定义水印位置和大小
python watermark.py /path/to/images /path/to/output --position top_right --font-size 40
# 递归处理子目录
python watermark.py /path/to/images /path/to/output --recursive
# 调整不透明度
python watermark.py /path/to/images /path/to/output --opacity 200
# 使用中文字体
python watermark.py /path/to/images /path/to/output --font-path "C:/Windows/Fonts/simhei.ttf"

视频水印脚本(可选)

如果需要处理视频文件,这里提供一个简单的视频水印脚本:

#!/usr/bin/env python3
"""
视频日期水印脚本
需要安装: pip install opencv-python
"""
import cv2
import os
import sys
from datetime import datetime
import argparse
def add_video_watermark(input_video, output_video, watermark_text, position='bottom_right',
                        font_size=30, opacity=0.5):
    """
    在视频上添加日期水印
    """
    try:
        # 打开视频
        cap = cv2.VideoCapture(input_video)
        if not cap.isOpened():
            print(f"无法打开视频: {input_video}")
            return False
        # 获取视频信息
        fps = int(cap.get(cv2.CAP_PROP_FPS))
        width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
        height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
        # 设置视频编码器
        fourcc = cv2.VideoWriter_fourcc(*'mp4v')
        out = cv2.VideoWriter(output_video, fourcc, fps, (width, height))
        # 设置字体
        font = cv2.FONT_HERSHEY_SIMPLEX
        font_scale = font_size / 30.0
        thickness = 2
        # 计算文本大小
        text_size = cv2.getTextSize(watermark_text, font, font_scale, thickness)[0]
        # 设置边距
        margin = 20
        frame_count = 0
        while True:
            ret, frame = cap.read()
            if not ret:
                break
            # 计算位置
            if position == 'top_left':
                x, y = margin, text_size[1] + margin
            elif position == 'top_right':
                x = width - text_size[0] - margin
                y = text_size[1] + margin
            elif position == 'bottom_left':
                x, y = margin, height - margin
            elif position == 'bottom_right':
                x = width - text_size[0] - margin
                y = height - margin
            else:  # center
                x = (width - text_size[0]) // 2
                y = (height + text_size[1]) // 2
            # 添加水印
            cv2.putText(frame, watermark_text, (x, y), font, font_scale, 
                       (255, 255, 255, int(255 * opacity)), thickness)
            out.write(frame)
            frame_count += 1
            # 进度显示
            if frame_count % 100 == 0:
                print(f"处理中... 第 {frame_count} 帧")
        cap.release()
        out.release()
        cv2.destroyAllWindows()
        print(f"✓ 已处理视频: {os.path.basename(input_video)}")
        return True
    except Exception as e:
        print(f"✗ 处理视频失败: {str(e)}")
        return False
def process_videos(input_dir, output_dir, watermark_text, position='bottom_right', font_size=30):
    """
    批量处理视频
    """
    supported_formats = ['.mp4', '.avi', '.mov', '.mkv', '.wmv', '.flv']
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)
    file_count = 0
    success_count = 0
    for filename in os.listdir(input_dir):
        ext = os.path.splitext(filename)[1].lower()
        if ext in supported_formats:
            file_count += 1
            input_path = os.path.join(input_dir, filename)
            output_path = os.path.join(output_dir, f"watermarked_{filename}")
            if add_video_watermark(input_path, output_path, watermark_text, position, font_size):
                success_count += 1
    print(f"\n处理完成!")
    print(f"总共扫描: {file_count} 个视频")
    print(f"成功处理: {success_count} 个视频")
if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='批量视频日期水印脚本')
    parser.add_argument('input_dir', help='输入视频目录')
    parser.add_argument('output_dir', nargs='?', default='video_output', help='输出目录')
    parser.add_argument('--date', default=None, help='自定义日期文本')
    parser.add_argument('--format', default='%Y-%m-%d', help='日期格式')
    parser.add_argument('--position', default='bottom_right', help='水印位置')
    parser.add_argument('--font-size', type=int, default=30, help='字体大小')
    args = parser.parse_args()
    # 检查输入目录
    if not os.path.exists(args.input_dir):
        print(f"错误: 输入目录不存在: {args.input_dir}")
        sys.exit(1)
    # 确定水印文本
    if args.date:
        watermark_text = args.date
    else:
        watermark_text = datetime.now().strftime(args.format)
    print(f"水印文本: {watermark_text}")
    print(f"处理目录: {args.input_dir}")
    print(f"输出目录: {args.output_dir}")
    print("-" * 50)
    process_videos(args.input_dir, args.output_dir, watermark_text, 
                  args.position, args.font_size)

使用说明

  1. 安装依赖:运行 pip install pillow(图片脚本)或 pip install opencv-python(视频脚本)

  2. 基本使用

    python watermark.py /path/to/images
  3. 高级选项:可根据需求调整位置、字体大小、透明度等参数

  4. 支持格式:图片支持 JPG/PNG/BMP/TIFF等,视频支持 MP4/AVI/MOV等

这个脚本会自动给所有图片/视频添加带有日期的水印,保持原始文件不变,将处理后的文件保存到输出目录。

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