[Python] PIL agrega marca de agua a las imágenes con la explicación de código más completa

Agregar marca de agua a las imágenes

El siguiente es un método para agregar una marca de agua, puede colocarlo en un archivo Python separado y luego llamar a este método donde necesita agregar una marca de agua:

from PIL import Image, ImageDraw, ImageFont


def add_watermark(image_path, text, font_path, font_size=40, fill=(255, 255, 255, 128)):
    """
    在图片上添加水印
    :param image_path: 图片路径
    :param text: 水印文本
    :param font_path: 字体文件路径
    :param font_size: 字体大小,默认为 40
    :param fill: 水印颜色,默认为白色半透明
    :return: None
    """
    with Image.open(image_path) as image:
        draw = ImageDraw.Draw(image)
        width, height = image.size
        font = ImageFont.truetype(font_path, font_size)
        text_width, text_height = draw.textsize(text, font=font)
        x = int((width - text_width) / 2)
        y = int((height - text_height) / 2)
        draw.text((x, y), text, font=font, fill=fill)
        image.save(image_path)

El método acepta cinco parámetros:

  • image_path: la ruta de la imagen que necesita ser filigrana;
  • text: texto de marca de agua;
  • font_path: ruta del archivo de fuente;
  • font_size: tamaño de fuente, el valor predeterminado es 40;
  • fill: color de marca de agua, el valor predeterminado es blanco y translúcido.

Puede modificar estos parámetros según sea necesario.

El código de muestra que utiliza este método es el siguiente:

add_watermark('image.jpg', 'Hello, world!', 'simsun.ttc', font_size=50)

Este código agregará una marca de agua a image.jpgla imagen con texto de Hello, world!, fuente de simsun.ttcy tamaño de fuente de 50.

explicación del parámetro de relleno:

fillEl parámetro especifica el color de la marca de agua. En la biblioteca PIL, un color se representa por un cuádruple. Los cuatro valores en el cuádruple representan rojo, verde, azul y transparencia respectivamente, y el rango de valores es de 0 a 255. Por ejemplo, (255, 0, 0, 128)para indicar translucidez roja.

En add_watermark()el método , fillconfiguramos el parámetro predeterminado para que (255, 255, 255, 128)sea blanco y translúcido, de modo que la marca de agua no cubra completamente la imagen original. Puede modificar este parámetro según sea necesario, por ejemplo, para cambiar el color de la marca de agua a rojo, puede modificar fillel parámetro a (255, 0, 0, 128).

explicación del parámetro textbbox

textbbox()El método es una función proporcionada por ImageDrawel módulo , que se utiliza para calcular el tamaño del rectángulo necesario para dibujar el texto. La sintaxis del método es la siguiente:

ImageDraw.Draw.textbbox(xy, text, font=None, spacing=0, align='left')

Entre ellos, el significado de cada parámetro es el siguiente:

  • xy: una tupla de dos (x, y)que indica la posición inicial del texto, es decir, las coordenadas de la esquina superior izquierda del cuadro de texto.
  • text: Indica el contenido del texto a dibujar.
  • font: representa un objeto de fuente, que se puede crear con ImageFont.truetype()el método .
  • spacing: Indica el espacio entre líneas, el valor predeterminado es 0.
  • align: Indica la alineación horizontal del texto, que puede ser 'left', 'center'o 'right'.

textbbox()El método calcula el tamaño del cuadro de texto en función de información como el contenido del texto, la fuente y la posición inicial, y devuelve una tupla de 4 que (x0, y0, x1, y1)indica las coordenadas de la esquina superior izquierda y la esquina inferior derecha del cuadro de texto. Entre ellos, (x0, y0)representa las coordenadas de la esquina superior izquierda del cuadro de texto y (x1, y1)representa las coordenadas de la esquina inferior derecha del cuadro de texto.

Al dibujar texto, podemos usar textbbox()el método para calcular primero el tamaño del cuadro de texto y luego calcular la posición del texto de acuerdo con el tamaño del cuadro de texto, para garantizar que el texto esté centrado o alineado a la izquierda en el imagen.

manejo de excepciones

mensaje de advertencia:

DeprecationWarning: textsize está obsoleto y se eliminará en Pillow 10 (2023-07-01). Utilice textbbox o textlength en su lugar. ancho_texto, altura_texto = dibujar.tamañotexto(texto, fuente=fuente)

Solución:

Esta advertencia se debe a que en una versión futura de la biblioteca Pillow, textsize()el método quedará obsoleto y se recomienda usar textbbox()el textlength()método o en su lugar. Por lo tanto, al escribir código, debemos evitar usar textsize()el método .

De acuerdo con el mensaje de advertencia, puede reemplazar textsize()el método con textbbox()el textlength()método . Por ejemplo, modifique el código anterior para:

width, height = image.size
draw = ImageDraw.Draw(image)
font = ImageFont.truetype(font_path, font_size)
text_width, text_height = draw.textbbox((0, 0), text, font=font)
x = int((width - text_width) / 2)
y = int((height - text_height) / 2)
draw.text((x, y), text, font=font, fill=fill)

En el código anterior, usamos textbbox()el método para calcular el ancho y el alto del texto, luego calculamos la posición del texto en la imagen de acuerdo con el tamaño de la imagen y el tamaño del texto, y finalmente dibujamos el texto en el imagen. Esto evita advertencias al usar textsize()el método .

excepción draw.textbbox

text_width, text_height = draw.textbbox((10, 10), text, font=font) Esta parte del código arroja una excepción Error: demasiados valores para desempaquetar (se esperaban 2)

Este error generalmente se debe a una falta de coincidencia entre la tupla de 4 devuelta por textbbox()el método y(x0, y0, x1, y1) la tupla de 2 esperada .(text_width, text_height)

Para solucionar esto, puede calcular el ancho y el alto del texto utilizando las coordenadas superior izquierda (x0, y0)e , por ejemplo:(x1, y1)

# 计算文本框大小
bbox = draw.textbbox((10, 10), text, font=font)

# 计算文本宽度和高度
text_width = bbox[2] - bbox[0]
text_height = bbox[3] - bbox[1]

Aquí, usamos para bbox[2] - bbox[0]calcular el ancho del texto y para bbox[3] - bbox[1]calcular la altura del texto. De esta manera, el ancho y la altura calculados se pueden almacenar en text_widthlas text_heightvariables y para su uso posterior.

Tenga en cuenta que al usar textbbox()el método , los valores en la tupla de 4 devuelta están en orden (x0, y0, x1, y1), por lo que debe extraer los valores correspondientes según sea necesario.

from PIL import Image, ImageDraw, ImageFont


def add_watermark(image_path, text, font_path, font_size=40, opacity=0.5, fill=(255, 102, 0, 128)):
    """
    在图片上添加水印
    :param image_path: 图片路径
    :param text: 水印文本
    :param font_path: 字体文件路径
    :param font_size: 字体大小,默认为 40
    :param opacity: 水印透明度,默认为 0.5
    :param fill: 水印颜色,默认为白色半透明
    :return: None
    """
    with Image.open(file_path) as image:
        draw = ImageDraw.Draw(image)
        width, height = image.size
        font = ImageFont.truetype(font_path, font_size)
        print(333)
        # text_width, text_height = draw.textbbox((10, 10), text, font=font)
        # 计算文本框大小
        bbox = draw.textbbox((10, 10), text, font=font)
        # 计算文本宽度和高度
        text_width = bbox[2] - bbox[0]
        text_height = bbox[3] - bbox[1]
        print(f"=== text_width, text_height  {
      
      text_width, text_height }")
        x = int((width - text_width) / 2)
        y = int((height - text_height) / 2)
        draw.text((x, y), text, font=font, fill=FILL)
        image.save(file_path)
Excepción de pantalla china

Imagen original
inserte la descripción de la imagen aquí

Método de llamada:

if __name__ == '__main__':
    
    add_watermark('test.png', '测试!', 'simsunb.ttf', font_size=50)

[Falló la transferencia de la imagen del enlace externo, el sitio de origen puede tener un mecanismo anti-leeching, se recomienda guardar la imagen y cargarla directamente (img-jYNI8pkj-1684290601180) (Excel y PIL.assets/image-20230517102532955.png)]

Esperamos que haya: ¡prueba! en el medio de la imagen, y la marca de agua se muestra en la imagen. Hemos visto el resultado real, y parece que todavía hay algo mal;

Simplemente modifique la referencia de la biblioteca de fuentes chinas

if __name__ == '__main__':

    # add_watermark('test.png', '测试!', 'simsunb.ttf', font_size=50)
    add_watermark('test.png', '测试!', r'C:\Windows\Fonts\微软雅黑\msyh.ttc', font_size=50)

[Falló la transferencia de la imagen del enlace externo, el sitio de origen puede tener un mecanismo de enlace antirrobo, se recomienda guardar la imagen y cargarla directamente (img-HzCecq1L-1684290601181) (Excel y PIL.assets/image-20230517102808833.png) ]

Justo ahora usé: C:\Windows\Fonts\Microsoft Yahei\msyh.ttc esta ruta, me gustaría mencionarles que esta es la ubicación de almacenamiento predeterminada de las fuentes del sistema de Windows;

En este punto, se ha realizado la operación básica de agregar una marca de agua a la imagen, así que probémoslo rápidamente;

Supongo que te gusta

Origin blog.csdn.net/qq_41604569/article/details/130720303
Recomendado
Clasificación