前言

之前 图片加水印 是对于静态图片,而现在这个是对动态图片 (.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

先删除 outinput 文件夹,再生成 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 (这个用于快速清理 inputout 的文件)

注意事项

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

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

1
path = 水印字体路径

最后

代码已上传到 githubgitee

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