Python 为图片添加水印

1. 安装 Python

1
$ pip install pillow

2. 创建加水印的 Python 脚本

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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/usr/bin/python
# -*- coding: utf-8 -*-

import os
import sys
import math
import shutil
import tinify

from PIL import Image, ImageFont, ImageDraw, ImageEnhance, ImageChops

opacity = 0.2 # 水印透明度,[0, 1]
padding = 150 # 水印间距
angle = 30 # 水印旋转角度
quality = 80 # 图片质量

word = 'itcoca.cn' # 水印文字
word_size = 50 # 文字大小
word_line = 1.2 # 文字行距
word_color = '#8B8B1B' # 文字颜色
word_font = 'C:\\Windows\\Fonts\\timesbd.ttf' # 字体
#word_font = '/usr/share/fonts/truetype/msttcorefonts/timesbd.ttf'

tinify.key = "xxx" # https://tinify.com/dashboard/api


def gen_mark():
"""
生成单个水印图片
"""

# 创建水印图片
width = len(word) * word_size
height = round(word_size * word_line)
mark = Image.new(mode='RGBA', size=(width, height))

# 生成文字
mark_draw = ImageDraw.Draw(im=mark)
mark_draw.text(xy=(0, 0),
text=word,
fill=word_color,
font=ImageFont.truetype(word_font, size=word_size))
del mark_draw

# 裁剪图片边缘空白
mark_bg = Image.new(mode='RGBA', size=mark.size)
diff = ImageChops.difference(mark, mark_bg)
del mark_bg
bbox = diff.getbbox()
if bbox:
mark = mark.crop(bbox)

# 设置水印透明度
alpha = ImageEnhance.Brightness(mark.split()[3]).enhance(opacity)
mark.putalpha(alpha)

return mark


def add_mark(image_path):
"""
为图片添加水印
"""

im = Image.open(image_path)
# 最大宽度800
im.thumbnail((800, 99999))

# 以斜边长度为宽高创建大图
c = int(math.sqrt(im.size[0] * im.size[0] + im.size[1] * im.size[1]))
mark = gen_mark()
mark2 = Image.new(mode='RGBA', size=(c, c))

# 在大图上生成水印文字
y, idx = 0, 0
while y < c:
# 制造x坐标错位
x = -int((mark.size[0] + padding) * 0.5 * idx)
idx = (idx + 1) % 2

while x < c:
# 在该位置粘贴mark水印图片
mark2.paste(mark, (x, y))
x = x + mark.size[0] + padding
y = y + mark.size[1] + padding

# 将大图旋转一定角度
mark2 = mark2.rotate(angle)

# 在原图上添加大图水印
if im.mode != 'RGBA':
im = im.convert('RGBA')
im.paste(mark2, # 大图
(int((im.size[0] - c) / 2), int((im.size[1] - c) / 2)), # 坐标
mask=mark2.split()[3])
del mark2

# 保存文件
if im:
if os.path.splitext(image_path)[1] != '.png':
im = im.convert('RGB')
im.save(image_path, optimize=True, quality=quality)
print('Success.')
else:
print('Failed.')


def bak_image(image_path):
arr = image_path.split('.')
arr.insert(-1, 'bak')
new_path = '.'.join(arr)
print(image_path, new_path)
shutil.copyfile(image_path, new_path)


def compress_image(image_path):
# 压缩
source = tinify.from_file(image_path)
source.to_file(image_path)


def main():
image_path = sys.argv[1]
bak_image(image_path)
add_mark(image_path)
compress_image(image_path)


if __name__ == '__main__':
main()

3. Windows 右键添加水印

4. KDE 右键添加水印

1
2
3
4
5
6
7
8
9
10
11
$ vi ~/.local/share/kservices5/ServiceMenus/watermark.desktop
[Desktop Entry]
Type=Service
ServiceTypes=KonqPopupMenu/Plugin
MimeType=image/*;
Actions=RunPythonScript;

[Desktop Action RunPythonScript]
Name=Watermark
Icon=system-run
Exec=/xxx/python /xxx/watermark.py %f