本文目录导读:

我来为您提供一个批量添加日期水印的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)
使用说明
-
安装依赖:运行
pip install pillow(图片脚本)或pip install opencv-python(视频脚本) -
基本使用:
python watermark.py /path/to/images
-
高级选项:可根据需求调整位置、字体大小、透明度等参数
-
支持格式:图片支持 JPG/PNG/BMP/TIFF等,视频支持 MP4/AVI/MOV等
这个脚本会自动给所有图片/视频添加带有日期的水印,保持原始文件不变,将处理后的文件保存到输出目录。