前言

之前 图片加水印 是对于静态图片,而现在这个是对动态图片 (.gif) 加水印。


原图

加水印后


部分代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
def add_watermark_to_gif(gif_path, watermark_text, output_path, font_path, font_color, font_size, position):
# 打开GIF图像
with Image.open(gif_path) as gif:
# 检查图像是否为GIF动画
if gif.is_animated:
# 获取GIF的帧数和持续时间
frames = []
durations = []
for i in range(gif.n_frames):
gif.seek(i)
frame = gif.copy().convert("RGBA") # 确保帧是RGBA模式
frames.append(frame)
durations.append(gif.info['duration'])

# 为每一帧添加水印
watermarked_frames = []
for frame in frames:
draw = ImageDraw.Draw(frame)
# 加载字体
font = ImageFont.truetype(font_path, font_size)

# 在指定位置绘制水印
draw.text(position, watermark_text, fill=font_color, font=font)
watermarked_frames.append(frame)

# 保存带有水印的GIF
watermarked_gif = frames[0]
watermarked_gif.save(
output_path,
save_all=True,
append_images=watermarked_frames[1:],
durations=durations,
loop=0
)
else:
# 如果GIF不是动画,只需为单帧添加水印
with Image.open(gif_path) as img:
img = img.convert("RGBA") # 确保图像是RGBA模式
draw = ImageDraw.Draw(img)
font = ImageFont.truetype(font_path, font_size)
draw.text(position, watermark_text, fill=font_color, font=font)
img.save(output_path)

ini 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def read_config(ini_path):
config = configparser.ConfigParser()
config.read(ini_path)

# 获取ini
watermark_text = config['diy']['text']
font_path = config['diy']['path']
font_color = tuple(map(int, config['diy']['color'].split(',')))
font_size = int(config['diy']['size'])
position = tuple(map(int, config['diy']['xy'].split(',')))
output = config['diy']['out']

return watermark_text, font_path, font_color, font_size, position, output

batch_add_watermark_to_gifs('input', 'user.ini')
1
2
3
4
5
6
7
[diy]
path = STXINGKA.TTF
size = 36
text = @Reverse
color = 0, 255, 255
xy = 50, 50
out = out
1
2
3
4
5
6
7
# ini备注
path 水印字体路径
size 水印字体大小
text 水印字体
color 水印字体颜色(RGB)
xy 水印位置坐标X,Y
out 处理后的文件路径

CMD

1
2
3
4
5
rd /s /q .\out

rd /s /q .\input

mkdir input

先删除 out 和 input 文件夹,再生成 input 文件夹


完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# 工程:test
# 创建时间:2024/6/24 23:20
# encoding:utf-8

from PIL import Image, ImageDraw, ImageFont
import os
import configparser


def read_config(ini_path):
config = configparser.ConfigParser()
config.read(ini_path)

# 获取ini
watermark_text = config['diy']['text']
font_path = config['diy']['path']
font_color = tuple(map(int, config['diy']['color'].split(',')))
font_size = int(config['diy']['size'])
position = tuple(map(int, config['diy']['xy'].split(',')))
output = config['diy']['out']

return watermark_text, font_path, font_color, font_size, position, output


def add_watermark_to_gif(gif_path, watermark_text, output_path, font_path, font_color, font_size, position):
# 打开GIF图像
with Image.open(gif_path) as gif:
# 检查图像是否为GIF动画
if gif.is_animated:
# 获取GIF的帧数和持续时间
frames = []
durations = []
for i in range(gif.n_frames):
gif.seek(i)
frame = gif.copy().convert("RGBA") # 确保帧是RGBA模式
frames.append(frame)
durations.append(gif.info['duration'])

# 为每一帧添加水印
watermarked_frames = []
for frame in frames:
draw = ImageDraw.Draw(frame)
# 加载字体
font = ImageFont.truetype(font_path, font_size)

# 在指定位置绘制水印
draw.text(position, watermark_text, fill=font_color, font=font)
watermarked_frames.append(frame)

# 保存带有水印的GIF
watermarked_gif = frames[0]
watermarked_gif.save(
output_path,
save_all=True,
append_images=watermarked_frames[1:],
durations=durations,
loop=0
)
else:
# 如果GIF不是动画,只需为单帧添加水印
with Image.open(gif_path) as img:
img = img.convert("RGBA") # 确保图像是RGBA模式
draw = ImageDraw.Draw(img)
font = ImageFont.truetype(font_path, font_size)
draw.text(position, watermark_text, fill=font_color, font=font)
img.save(output_path)


def batch_add_watermark_to_gifs(gif_folder, ini_path):
watermark_text, font_path, font_color, font_size, position, output = read_config(ini_path)

# 确保输出文件夹存在
if not os.path.exists(output):
os.makedirs(output)

# 遍历GIF文件夹中的所有文件
for filename in os.listdir(gif_folder):
if filename.lower().endswith('.gif'):
input_path = os.path.join(gif_folder, filename)
output_path = os.path.join(output, filename)
add_watermark_to_gif(input_path, watermark_text, output_path, font_path, font_color, font_size, position)

print(f"{filename}")

batch_add_watermark_to_gifs('input', 'user.ini')

print('图片已批量处理完成!')


使用教程(打包整理后文件)

这里的步骤跟 Python 日记 - 图片加水印 一致

  1. 打开 user.ini , 里面的配置可自行修改

  2. 把将要处理的图片全部放到 input 文件夹中

  3. 双击运行 main.exe

  4. 等待窗口运行

  5. 处理后的图片在 out 中

  6. 双击 删除.bat (这个用于快速清理 input 和 out 的文件)

注意事项

  1. 图片只支持 gif 格式图片

  2. 如果需要改字体文件,还需要在 user.ini 里修改水印字体路径

1
path = 水印字体路径

最后

代码已上传到 github 和 gitee

打包整理后文件 蓝奏云 密码:9g98