Python案例如何用Pillow添加水印

wen python案例 2

本文目录导读:

Python案例如何用Pillow添加水印

  1. 安装Pillow
  2. 文字水印
  3. 图片水印
  4. 批量添加水印
  5. 斜向水印(防篡改)
  6. 实用函数:带参数控制
  7. 使用建议

我来介绍几种使用Pillow库给图片添加水印的方法:

安装Pillow

pip install Pillow

文字水印

基础文字水印

from PIL import Image, ImageDraw, ImageFont
def add_text_watermark(input_image_path, output_image_path, text="Watermark"):
    # 打开图片
    image = Image.open(input_image_path)
    # 创建绘图对象
    draw = ImageDraw.Draw(image)
    # 获取图片尺寸
    width, height = image.size
    # 设置字体(如果系统中没有该字体,会自动使用默认字体)
    try:
        font = ImageFont.truetype("arial.ttf", 36)
    except:
        font = ImageFont.load_default()
    # 计算文字位置(右下角)
    text_bbox = draw.textbbox((0, 0), text, font=font)
    text_width = text_bbox[2] - text_bbox[0]
    text_height = text_bbox[3] - text_bbox[1]
    # 设置位置(右下角,留出10像素边距)
    position = (width - text_width - 10, height - text_height - 10)
    # 添加文字(白色,半透明)
    draw.text(position, text, fill=(255, 255, 255, 128), font=font)
    # 保存图片
    image.save(output_image_path)
# 使用示例
add_text_watermark("input.jpg", "output_watermark.jpg", "My Watermark")

半透明文字水印

from PIL import Image, ImageDraw, ImageFont, ImageEnhance
def add_transparent_text_watermark(input_path, output_path, text="Watermark"):
    # 打开原图
    original = Image.open(input_path).convert("RGBA")
    # 创建透明层
    watermark = Image.new("RGBA", original.size, (0, 0, 0, 0))
    draw = ImageDraw.Draw(watermark)
    # 设置字体
    try:
        font = ImageFont.truetype("arial.ttf", 50)
    except:
        font = ImageFont.load_default()
    # 计算文字位置(中心)
    width, height = original.size
    text_bbox = draw.textbbox((0, 0), text, font=font)
    text_width = text_bbox[2] - text_bbox[0]
    text_height = text_bbox[3] - text_bbox[1]
    x = (width - text_width) // 2
    y = (height - text_height) // 2
    # 添加半透明文字(RGBA,A=128表示50%透明度)
    draw.text((x, y), text, fill=(255, 255, 255, 128), font=font)
    # 合并原图和透明层
    watermarked = Image.alpha_composite(original, watermark)
    # 保存(转为RGB如果不需透明度)
    watermarked = watermarked.convert("RGB")
    watermarked.save(output_path)
add_transparent_text_watermark("input.jpg", "output_transparent.jpg", "水印")

图片水印

基础图片水印

from PIL import Image
def add_image_watermark(input_image_path, watermark_image_path, output_image_path, position="bottom-right"):
    # 打开原图和水印图
    original = Image.open(input_image_path)
    watermark = Image.open(watermark_image_path)
    # 调整水印大小(建议为原图的10%)
    width, height = original.size
    watermark_size = int(min(width, height) * 0.1)
    watermark = watermark.resize((watermark_size, watermark_size), Image.Resampling.LANCZOS)
    # 水印位置
    if position == "bottom-right":
        x = width - watermark.width - 10
        y = height - watermark.height - 10
    elif position == "bottom-left":
        x = 10
        y = height - watermark.height - 10
    elif position == "top-right":
        x = width - watermark.width - 10
        y = 10
    elif position == "top-left":
        x = 10
        y = 10
    elif position == "center":
        x = (width - watermark.width) // 2
        y = (height - watermark.height) // 2
    # 添加水印
    if original.mode != "RGBA":
        original = original.convert("RGBA")
    if watermark.mode != "RGBA":
        watermark = watermark.convert("RGBA")
    # 粘贴水印
    original.paste(watermark, (x, y), watermark)
    # 保存
    original = original.convert("RGB")
    original.save(output_image_path)
# 使用示例
add_image_watermark("input.jpg", "logo.png", "output_logo.jpg", "bottom-right")

批量添加水印

import os
from PIL import Image, ImageDraw, ImageFont
def batch_add_watermark(folder_path, output_folder, text="水印"):
    # 创建输出文件夹
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    # 获取所有图片文件
    image_extensions = ['.jpg', '.jpeg', '.png', '.bmp', '.gif']
    for filename in os.listdir(folder_path):
        if any(filename.lower().endswith(ext) for ext in image_extensions):
            input_path = os.path.join(folder_path, filename)
            output_path = os.path.join(output_folder, f"watermarked_{filename}")
            # 添加水印
            add_text_watermark(input_path, output_path, text)
            print(f"Processed: {filename}")
# 使用示例
batch_add_watermark("images/", "watermarked_images/", "Copyright 2024")

斜向水印(防篡改)

from PIL import Image, ImageDraw, ImageFont
import math
def add_diagonal_watermark(input_path, output_path, text="Confidential"):
    image = Image.open(input_path).convert("RGBA")
    width, height = image.size
    # 创建透明层
    watermark = Image.new("RGBA", image.size, (0, 0, 0, 0))
    draw = ImageDraw.Draw(watermark)
    # 设置字体
    font_size = int(min(width, height) * 0.05)
    try:
        font = ImageFont.truetype("arial.ttf", font_size)
    except:
        font = ImageFont.load_default()
    # 计算对角线长度和角度
    diagonal_length = int(math.sqrt(width**2 + height**2))
    angle = math.degrees(math.atan2(height, width))
    # 创建旋转后的文字
    text_bbox = draw.textbbox((0, 0), text, font=font)
    text_width = text_bbox[2] - text_bbox[0]
    text_height = text_bbox[3] - text_bbox[1]
    # 重复添加水印形成背景效果
    for i in range(-diagonal_length, diagonal_length + 1, font_size * 3):
        for j in range(-diagonal_length, diagonal_length + 1, font_size * 3):
            draw.text((i, j), text, fill=(255, 255, 255, 50), font=font)
    # 旋转水印
    watermark = watermark.rotate(-angle, expand=0)
    # 合并
    watermarked = Image.alpha_composite(image, watermark)
    watermarked = watermarked.convert("RGB")
    watermarked.save(output_path)
# 使用示例
add_diagonal_watermark("input.jpg", "output_diagonal.jpg", "保密")

实用函数:带参数控制

from PIL import Image, ImageDraw, ImageFont, ImageEnhance
class WatermarkAdder:
    def __init__(self):
        self.font_path = None
    def add_watermark(self, image_path, output_path, text=None, image_watermark=None,
                     opacity=0.5, position="center", font_size=None):
        """
        添加水印的通用函数
        参数:
            image_path: 原图路径
            output_path: 输出路径
            text: 文字水印内容
            image_watermark: 图片水印路径
            opacity: 透明度 (0-1)
            position: 位置 (center, top-left, top-right, bottom-left, bottom-right)
            font_size: 字体大小
        """
        original = Image.open(image_path).convert("RGBA")
        width, height = original.size
        # 创建透明层
        watermark = Image.new("RGBA", original.size, (0, 0, 0, 0))
        if text:
            # 文字水印
            draw = ImageDraw.Draw(watermark)
            # 设置字体大小
            if font_size is None:
                font_size = int(min(width, height) * 0.03)
            try:
                font = ImageFont.truetype("arial.ttf", font_size)
            except:
                font = ImageFont.load_default()
            # 计算位置
            text_bbox = draw.textbbox((0, 0), text, font=font)
            text_width = text_bbox[2] - text_bbox[0]
            text_height = text_bbox[3] - text_bbox[1]
            positions = {
                "center": ((width - text_width) // 2, (height - text_height) // 2),
                "top-left": (10, 10),
                "top-right": (width - text_width - 10, 10),
                "bottom-left": (10, height - text_height - 10),
                "bottom-right": (width - text_width - 10, height - text_height - 10)
            }
            pos = positions.get(position, positions["center"])
            alpha = int(255 * opacity)
            draw.text(pos, text, fill=(255, 255, 255, alpha), font=font)
        elif image_watermark:
            # 图片水印
            wm_image = Image.open(image_watermark).convert("RGBA")
            # 调整水印大小
            wm_size = int(min(width, height) * 0.1)
            wm_image = wm_image.resize((wm_size, wm_size), Image.Resampling.LANCZOS)
            # 调整透明度
            if opacity < 1.0:
                alpha = wm_image.split()[3]
                alpha = alpha.point(lambda x: x * opacity)
                wm_image.putalpha(alpha)
            # 计算位置
            positions = {
                "center": ((width - wm_image.width) // 2, (height - wm_image.height) // 2),
                "top-left": (10, 10),
                "top-right": (width - wm_image.width - 10, 10),
                "bottom-left": (10, height - wm_image.height - 10),
                "bottom-right": (width - wm_image.width - 10, height - wm_image.height - 10)
            }
            pos = positions.get(position, positions["bottom-right"])
            watermark.paste(wm_image, pos, wm_image)
        # 合并
        result = Image.alpha_composite(original, watermark)
        result = result.convert("RGB")
        result.save(output_path)
# 使用示例
adder = WatermarkAdder()
# 文字水印
adder.add_watermark("input.jpg", "output1.jpg", 
                   text="Copyright 2024", 
                   opacity=0.6, 
                   position="bottom-right")
# 图片水印
adder.add_watermark("input.jpg", "output2.jpg", 
                   image_watermark="logo.png", 
                   opacity=0.4, 
                   position="center")

使用建议

  1. 水印位置:根据图片内容选择合适位置,通常是角落或中心
  2. 透明度:不要过低影响原图效果,不要过高容易被去除
  3. 字体选择:选择清晰易读的字体
  4. 批量处理:对大量图片使用循环处理
  5. 质量保持:保存时注意图片质量设置

这些方法基本覆盖了常见的水印添加需求,你可以根据具体场景选择合适的方法。

抱歉,评论功能暂时关闭!