python图片批量添加水印

问题起因

由于某实验课实验报告中的每张图片都需要添加水印,而一次实验可能有几十张图片,每次添加水印都费时费力。为解决这一麻烦事,本页介绍python批量添加图片水印的方法。

环境

python 3.7.3

Pycharm

依赖库

Pillow库

步骤

1.添加单个图片水印:

提供两种添加方法:

一种是添加有背景的水印

一种是自适应待添加区域颜色的水印,使水印与背景色尽可能不冲突

def add_watermark(filename, text, flag):
    font = ImageFont.truetype('msyh.ttf', 30)
    image = Image.open(filename)
    w = image.width
    h = image.height
    draw = ImageDraw.Draw(image)
    # 判断水印是否清晰
    pixels = image.load()
    if flag:
        for i in range(w - 165, w, 1):
            for j in range(h-40, h, 1):
                pixels[i, j] = (220, 220, 220)
        rgb = (0, 0, 0)
    else:
        crop_img = image.crop((w - 165, h - 40, w, h))
    	avg_rgb = get_dominant_color(crop_img) # 获取图片支配色
        if avg_rgb[0] <= 128 and avg_rgb[1] <= 128 and avg_rgb[2] <= 128:
            rgb = (255, 0, 0)  # 深色 添加红色水印以加强对比度
        else:
            rgb = (0, 0, 0)  # 浅色 添加黑色水印
    draw.text((w - 165, h - 40), text, rgb, font=font)
    image.save(os.path.dirname(__file__) + '/output/' + filename[0:-4] + '_marked.' + filename[-3:])

2.计算待添加水印区域的支配色的函数get_dominant_color

def get_dominant_color(image):  # 返回图片的主要色
    image = image.convert('RGBA')
    image.thumbnail((200, 200))
    max_score = 0
    dominant_color = 0
    for count, (r, g, b, a) in image.getcolors(image.size[0] * image.size[1]):
        # 跳过纯黑色
        if a == 0:
            continue
        saturation = colorsys.rgb_to_hsv(r / 255.0, g / 255.0, b / 255.0)[1]
        y = min(abs(r * 2104 + g * 4130 + b * 802 + 4096 + 131072) >> 13, 235)
        y = (y - 16.0) / (235 - 16)
        if y > 0.9:
            continue
        score = (saturation + 0.1) * count
        if score > max_score:
            max_score = score
            dominant_color = (r, g, b)
    return dominant_color

3.main函数:遍历当前目录所有指定后缀的图像文件,并对其添加水印

if __name__ == '__main__':
    d = os.path.dirname(__file__)
    a = os.listdir(d)
    flag = 1  # 是否加背景色以防止原图背景与水印冲突,建议添加 1:水印添加背景 0:水印不添加背景
    # 注:如果选择不添加背景色,将根据添加水印区域的平均rgb判断,浅色添加黑色水印,深色添加红色水印
    name = "E********"  # 水印信息
    suffix = ['png', 'jpg']  # 需要添加水印的图片类型列表
    if not os.path.isdir(d + '/output'):  # 创建输出目录
        os.makedirs(d + '/output')
    for i in a:
        if i[-3:] in suffix:
            add_watermark(i, name, flag)

Python代码

# -*- coding: utf-8 -*-
# Created by bladchan
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
import os
import colorsys


def get_dominant_color(image):  # 返回图片的主要色
    image = image.convert('RGBA')
    image.thumbnail((200, 200))
    max_score = 0
    dominant_color = 0
    for count, (r, g, b, a) in image.getcolors(image.size[0] * image.size[1]):
        # 跳过纯黑色
        if a == 0:
            continue
        saturation = colorsys.rgb_to_hsv(r / 255.0, g / 255.0, b / 255.0)[1]
        y = min(abs(r * 2104 + g * 4130 + b * 802 + 4096 + 131072) >> 13, 235)
        y = (y - 16.0) / (235 - 16)
        if y > 0.9:
            continue
        score = (saturation + 0.1) * count
        if score > max_score:
            max_score = score
            dominant_color = (r, g, b)
    return dominant_color


def add_watermark(filename, text, flag):
    font = ImageFont.truetype('msyh.ttf', 30)
    image = Image.open(filename)
    w = image.width
    h = image.height
    draw = ImageDraw.Draw(image)
    # 判断水印是否清晰
    pixels = image.load()
    if flag:
        for i in range(w - 165, w, 1):
            for j in range(h-40, h, 1):
                pixels[i, j] = (220, 220, 220)
        rgb = (0, 0, 0)
    else:
        crop_img = image.crop((w - 165, h - 40, w, h))
        avg_rgb = get_dominant_color(crop_img)
        if avg_rgb[0] <= 128 and avg_rgb[1] <= 128 and avg_rgb[2] <= 128:
            rgb = (255, 0, 0)  # 深色 添加红色水印以加强对比度
        else:
            rgb = (0, 0, 0)  # 浅色 添加黑色水印
    draw.text((w - 165, h - 40), text, rgb, font=font)
    image.save(os.path.dirname(__file__) + '/output/' + filename[0:-4] + '_marked.' + filename[-3:])


if __name__ == '__main__':
    d = os.path.dirname(__file__)
    a = os.listdir(d)
    flag = 1  # 是否加背景色以防止原图背景与水印冲突,建议添加 1:水印添加背景 0:水印不添加背景
    # 注:如果选择不添加背景色,将根据添加水印区域的平均rgb判断,浅色添加黑色水印,深色添加红色水印
    name = "E********"  # 水印信息
    suffix = ['png', 'jpg']  # 需要添加水印的图片类型列表
    if not os.path.isdir(d + '/output'):  # 创建输出目录
        os.makedirs(d + '/output')
    for i in a:
        if i[-3:] in suffix:
            add_watermark(i, name, flag)

效果图

添加背景色:

不添加背景色:

项目地址:

https://github.com/bladchan/watermark