1 简单引入

  • 往常咱们想给某些图片增加文字水印,办法有许多,也有许多的工具能够便利的进行;
  • 今日首要是对PIL库的应用,结合Python言语批量对图片增加水印;
  • 这儿需求留意的是图片的格式,不能为JPG或JPEG,由于这两种格式的图片不支撑透明度设置。

2 关于PIL

之前有的文章已经详细介绍过,这儿不再赘述了。

  • PILPython的一个图画处理库,支撑多种文件格式;
  • PIL提供强大的图画处理和图形处理才能;
  • 可完成对图画的缩放、裁剪、叠加以及图画增加线条、图画和文字等操作。
  • 装置的话,使用以下命令:
pip install Pillow

PIL怎么批量给图片增加文字水印?

3 本文涉及的PIL的几个类

模块或类 阐明
image模块 用于对图画就行处理
ImageDraw 2D图画目标
ImageFont 存储字体
ImageEnhance 图画增强

4 完成原理

本文首要目的是批量对某个文件夹下的图片进行增加水印,原理如下:

  • 对水印内容设置;
  • 使用Image目标的open()办法翻开原始图片;
  • 使用Image目标的new()办法新建存储水印图片目标;
  • 使用Image.Draw.Draw目标的text()制作水印文字;
  • 使用ImageEnhance中的Brightness中的enhance()设置水印透明度。

5 完成进程

5.1 原始图片

  • 咱们设置一个原始图片的存储目录,比方:
F:python_studyimageimage01
  • 这个文件夹中存放了多个png格式的图片:
    PIL怎么批量给图片增加文字水印?
  • 这儿的一个原始图片为:
    PIL怎么批量给图片增加文字水印?

5.2 导入相关模块

  • 导入需求的几个PIL中的模块或类:
from PIL import Image, ImageDraw, ImageFont, ImageEnhance
import os

5.3 初始化数据

  • 咱们这儿料想的是,通过用户自己手动输入相关信息,比方图片的存储途径,需求设置的水印文字,通过输入的办法设置水印的方位,设置水印的透明度等;
class TestText():
    def __init__(self):
        super(TestText, self).__init__()
        self.pic_path = input('图片途径:')
        self.pic_text = input('水印文字:')
        self.p_flag = int(input('水印方位(1:左上角,2:左下角,3:右上角,4:右下角,5:居中):'))
        self.a = float(input('水印透明度(0—1之间的1位小数):'))

5.4 水印字体设置

  • 这儿咱们先看下ImageFont.truetype源码:
def truetype(font=None, size=10, index=0, encoding="", layout_engine=None):
    """
    Load a TrueType or OpenType font from a file or file-like object,
    and create a font object.
    This function loads a font object from the given file or file-like
    object, and creates a font object for a font of the given size.
    Pillow uses FreeType to open font files. On Windows, be aware that FreeType
    will keep the file open as long as the FreeTypeFont object exists. Windows
    limits the number of files that can be open in C at once to 512, so if many
    fonts are opened simultaneously and that limit is approached, an
    ``OSError`` may be thrown, reporting that FreeType "cannot open resource".
    A workaround would be to copy the file(s) into memory, and open that instead.
    This function requires the _imagingft service.
    :param font: A filename or file-like object containing a TrueType font.
                 If the file is not found in this filename, the loader may also
                 search in other directories, such as the :file:`fonts/`
                 directory on Windows or :file:`/Library/Fonts/`,
                 :file:`/System/Library/Fonts/` and :file:`~/Library/Fonts/` on
                 macOS.
    :param size: The requested size, in pixels.
    :param index: Which font face to load (default is first available face).
    :param encoding: Which font encoding to use (default is Unicode). Possible
                     encodings include (see the FreeType documentation for more
                     information):
  • 它的大意就是从体系中的字体库中读取字体;
  • 那咱们的体系字体在哪里呢?
  • 体系字体在
C:WindowsFonts
  • 如下:
    PIL怎么批量给图片增加文字水印?
  • 咱们随便选一个自己喜爱的字体,仿制下姓名即可:
self.font = ImageFont.truetype("cambriab.ttf", size=35)

5.5 翻开原始图片并新建存储目标

  • 翻开原始图片,并转换为RGB
image = Image.open(img).convert('RGBA')
  • 创立制作目标:
new_img = Image.new('RGBA', image.size, (255, 255, 255, 0))
image_draw = ImageDraw.Draw(new_img)

5.6 计算图片和水印的巨细

  • 图片巨细:
w, h = image.size
  • 文字巨细:
w1 = self.font.getsize(self.pic_text)[0]  # 获取字体宽度
h1 = self.font.getsize(self.pic_text)[1]  # 获取字体高度

5.7 选择性设置水印文字

  • 通过if语句来完成:
 if self.p_flag == 1:  # 左上角
      location = (0, 0)
 elif self.p_flag == 2:  # 左下角
      location = (0, h - h1)
 elif self.p_flag == 3:  # 右上角
      location = (w - w1, 0)
 elif self.p_flag == 4:  # 右下角
      location = (w - w1, h - h1)
 elif self.p_flag == 5:  # 居中
      location = (h/2, h/2)

5.8 制作文字并设置透明度

  • 制作文字:
image_draw.text(location, self.pic_text, font=self.font, fill="blue")
  • 设置透明度
 transparent = new_img.split()[3]
 transparent = ImageEnhance.Brightness(transparent).enhance(self.a)
 new_img.putalpha(transparent)
 Image.alpha_composite(image, new_img).save(img)

5.9 遍历获取图片文件并调用制作办法

 text_pic = TestText()
    try:
        file_list = os.listdir(text_pic.pic_path)
        for i in range(0, len(file_list)):
            filepath = os.path.join(text_pic.pic_path, file_list[i])  
            if os.path.isfile(filepath): 
                filetype = os.path.splitext(filepath)[1] 
                if filetype == '.png': 
                    text_pic.test_text(filepath) 
                else:
                    print("图片格式有误,无法增加水印,请使用png格式图片")
        print('批量增加水印完成')
    except:
        print('输入的文件途径有误,请查看~~')

6 完好源码

# -*- coding:utf-8 -*-
# 作者:虫无涯
# 日期:2023/11/21 
# 文件名称:test_text_pic.py
# 作用:批量给图片增加文字水印和图片水印
# 联络:VX(NoamaNelson)
# 博客:https://blog.csdn.net/NoamaNelson
from PIL import Image, ImageDraw, ImageFont, ImageEnhance
import os
class TestText():
    def __init__(self):
        super(TestText, self).__init__()
        self.pic_path = input('图片途径:')
        self.pic_text = input('水印文字:')
        self.p_flag = int(input('水印方位(1:左上角,2:左下角,3:右上角,4:右下角,5:居中):'))
        self.a = float(input('水印透明度(0—1之间的1位小数):'))
        # 设置字体
        self.font = ImageFont.truetype("cambriab.ttf", size=35)
    # 文字水印
    def test_text(self, img):
        global location
        image = Image.open(img).convert('RGBA') 
        new_img = Image.new('RGBA', image.size, (255, 255, 255, 0)) 
        image_draw = ImageDraw.Draw(new_img) 
        w, h = image.size  # 图片巨细
        w1 = self.font.getsize(self.pic_text)[0]  # 字体宽度
        h1 = self.font.getsize(self.pic_text)[1]  # 字体高度
        # 设置水印文字方位
        if self.p_flag == 1:  # 左上角
            location = (0, 0)
        elif self.p_flag == 2:  # 左下角
            location = (0, h - h1)
        elif self.p_flag == 3:  # 右上角
            location = (w - w1, 0)
        elif self.p_flag == 4:  # 右下角
            location = (w - w1, h - h1)
        elif self.p_flag == 5:  # 居中
            location = (h/2, h/2)
        # 制作文字
        image_draw.text(location, self.pic_text, font=self.font, fill="blue")
        # 设置透明度
        transparent = new_img.split()[3]
        transparent = ImageEnhance.Brightness(transparent).enhance(self.a)
        new_img.putalpha(transparent)
        Image.alpha_composite(image, new_img).save(img)
if __name__ == "__main__":
    text_pic = TestText()
    try:
        file_list = os.listdir(text_pic.pic_path) 
        for i in range(0, len(file_list)): 
            filepath = os.path.join(text_pic.pic_path, file_list[i])
            if os.path.isfile(filepath): 
                filetype = os.path.splitext(filepath)[1] 
                if filetype == '.png': 
                    text_pic.test_text(filepath) 
        print('批量增加水印完成')
    except:
        print('输入的文件途径有误,请查看~~')

7 显示作用

  • 运行进程:
D:Python37python.exe F:/python_study/python_project/test_text_pic.py
图片途径:F:python_studyimageimage01
水印文字:@虫无涯
水印方位(1:左上角,2:左下角,3:右上角,4:右下角,5:居中):1
水印透明度(01之间的1位小数):0.5
F:/python_study/python_project/test_text_pic.py:32: DeprecationWarning: getsize is deprecated and will be removed in Pillow 10 (2023-07-01). Use getbbox or getlength instead.
  w1 = self.font.getsize(self.pic_text)[0]  # 获取字体宽度
F:/python_study/python_project/test_text_pic.py:33: DeprecationWarning: getsize is deprecated and will be removed in Pillow 10 (2023-07-01). Use getbbox or getlength instead.
  h1 = self.font.getsize(self.pic_text)[1]  # 获取字体高度
批量增加水印完成
  • 不同方位的水印作用:
    PIL怎么批量给图片增加文字水印?
  • 居中作用:
    PIL怎么批量给图片增加文字水印?