使用PIL为图片添加水印[python]
问题描述
最近遇到有需要使用证件的情况,但是直接发送证件照片可能存在安全风险,所以考虑在手机上找个软件给证件添加水印(满屏水印那种,不是单个水印)。但是在应用商店下了几个软件,有可以使用的但是非VIP用户有次数限制,很是烦人。
所有决定自己用Python的PIL库搞一个小脚本处理它,同时证件照片在自己本地处理也比较放心,不用担心照片被app上传到服务器的风险。
代码实现
项目地址:https://github.com/MingruiWang2017/add_watermark.git
需要安装依赖:pip install pillow argparse
import os
import sys
import argparse
from PIL import Image, ImageDraw, ImageFont, ImageEnhance
def read_origin_photo(photo_path, photo_angle=0):
"""
获取图像内容与尺寸
photo_path:图片路径
photo_angle: 图片旋转角度
"""
origin_photo = Image.open(photo_path)
origin_photo = origin_photo.convert('RGBA')
origin_photo = origin_photo.rotate(photo_angle, expand=True)
h, w = origin_photo.size
return origin_photo, h, w
# def get_color(text_color):
# r = int(text_color[1:3], base=16)
# g = int(text_color[3:5], base=16)
# b = int(text_color[5:7], base=16)
# return r, g, b
def make_text_picture(h, w, text, font_path, font_size=40, angle=-45, color=(0, 0, 0)):
"""
制作水印图片
h: 原图高度
w: 原图宽度
font_path:字体文件路径
font_size:字体大小
angle:字体旋转角度
color:字体颜色
"""
text_pic = Image.new('RGBA', (4 * h, 4 * w), (255, 255, 255, 255))
fnt = ImageFont.truetype(font_path, size=font_size)
text_d = ImageDraw.Draw(text_pic)
# a, b 分别控制水印的列间距和行间距,默认为字体的2倍列距,4倍行距
a, b = 2, 4
for x in range(10, text_pic.size[0] - 10, a * font_size * len(text)):
for y in range(10, text_pic.size[1] - 10, b * font_size):
text_d.multiline_text((x, y), text, fill=color, font=fnt)
# 旋转水印
text_pic = text_pic.rotate(angle)
# 截取水印部分图片
text_pic = text_pic.crop((h, w, 3 * h, 3 * w))
# text_pic.show()
return text_pic
def combine(origin_photo, text_pic, alpha=0.2, out_name='out.jpg'):
"""
为图片添加水印并保存
origin_photo: 原图内容
text_pic: 要添加的水印图片
alpha:水印的不透明度
out_name: 输出图片的文件名
"""
# 合并水印图片和原图
text_pic = text_pic.resize(origin_photo.size)
out = Image.blend(origin_photo, text_pic, alpha)
out = out.convert('RGB')
# 增强图片对比度
enhance = ImageEnhance.Contrast(out)
out = enhance.enhance(1.0 / (1 - alpha))
out_path = os.path.join('./out_images/', out_name)
out.save(out_path)
out.show()
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('photo_path', help='图片路径,如:1.jpg或./images/1.jpg')
parser.add_argument('text', help="要添加的水印内容")
parser.add_argument('--photo_angle', dest='photo_angle', default=0,
help='原图片旋转角度,默认为0,不进行旋转')
parser.add_argument('--new_image_name', dest='new_image_name', default=None,
help='输出图片的名称, 默认为"原图片名_with_watermark.jpg", 图片保存在out_images目录下')
parser.add_argument('--font_path', dest='font_path', default=r"./fonts/STSONG.TTF",
help='要使用的字体路径,如 STSONG.TTF,windows可在C:\Windows\Fonts查找字体')
parser.add_argument('--text_angle', dest='text_angle', default=-45,
help='水印的旋转角度,0为水平,-90位从上向下垂直, 90为从下向上垂直,默认-45')
parser.add_argument('--text_color', dest='text_color', default='#000000',
help="水印颜色,默认#000000(黑色)")
parser.add_argument('--text_size', dest='text_size',
default=40, help='水印字体的大小, 默认40')
parser.add_argument('--text_alpha', dest='text_alpha',
default=0.2, help='水印的不透明度,建议0.2~0.3,默认0.2')
args = parser.parse_args()
photo_path = args.photo_path
text = args.text
if not photo_path or not text:
print('必须指定图片路径和水印文字')
sys.exit(-1)
photo_angle = int(args.photo_angle)
font_path = args.font_path
text_size = int(args.text_size)
text_angle = int(args.text_angle)
origin_photo, h, w = read_origin_photo(photo_path, photo_angle)
text_pic = make_text_picture(h, w, text, font_path,
font_size=text_size, angle=text_angle, color=args.text_color)
new_image_name = args.new_image_name
photo_name = os.path.split(photo_path)[-1].split('.')[0] # 获取图片名称
if new_image_name is None:
new_image_name = photo_name + '_with_watermark.jpg'
combine(origin_photo, text_pic, alpha=float(args.text_alpha),
out_name=new_image_name)
使用方法
可以通过python add_text.py --help
命令查看帮助文档,其中add_text.py
是脚本的名称,可以按自己喜好更换。
在windows环境下测试使用,字体文件可以从windows字体库中选择,位置为C:\Windows\Fonts
。
D:\code>python add_text.py --help
usage: add_watermark.py [-h] [--photo_angle PHOTO_ANGLE] [--new_image_name NEW_IMAGE_NAME] [--font_path FONT_PATH]
[--text_angle TEXT_ANGLE] [--text_color TEXT_COLOR] [--text_size TEXT_SIZE] [--text_alpha TEXT_ALPHA]
photo_path text
positional arguments:
photo_path 图片路径,如:1.jpg或./images/1.jpg
text 要添加的水印内容
options:
-h, --help show this help message and exit
--photo_angle PHOTO_ANGLE
原图片旋转角度,默认为0,不进行旋转
--new_image_name NEW_IMAGE_NAME
输出图片的名称, 默认为"原图片名_with_watermark.jpg", 图片保存在out_images目录下
--font_path FONT_PATH
要使用的字体路径,如 STSONG.TTF,windows可在C:\Windows\Fonts查找字体
--text_angle TEXT_ANGLE
水印的旋转角度,0为水平,-90位从上向下垂直, 90为从下向上垂直,默认-45
--text_color TEXT_COLOR
水印颜色,默认#000000(黑色)
--text_size TEXT_SIZE
水印字体的大小, 默认40
--text_alpha TEXT_ALPHA
水印的不透明度,建议0.2~0.3,默认0.2
使用效果
以下命令基于github项目目录结构执行,如果只是复制了上面的脚本,需要修改脚本中的字体路径和图片输出路径。
建议直接clone git仓库进行操作或测试。
原图:
添加水印:python add_watermark.py ./images/1.jpg "房东的猫"
结果显示图片的对比度会出现下降。不过放在证件上问题不大。
更换字体和颜色:
python add_watermark.py --new_image_name="2.jpg" --text_color="#0000FF" --font_path="./fonts/简卡通.TTF" --text_alpha=0.1 ./images/1.jpg "寄 没有地址的信"