【Python】图片加水印 - 无损高清 - 性能强劲版

一、引言

  • 在技术课程、文案处理创作中,本着分享的初心,但经常遇到辛苦创作的内容被拿去售卖的情况,因此为图片添加水印是保护版权和增加抄袭成本的有效手段。
  • 本文基于Python的Pillow库,提供【无损高清水印】的添加方案,支持透明度调节与批量处理,确保输出画质不受损。

二、技术方案与优势

1.无损处理原理

  • 通过RGBA模式保留原始图像的Alpha通道,避免JPEG压缩导致的画质损失,最终可保存为PNG或JPEG等格式图片。
  • 双模式水印支持
    • 文字水印:自定义字体、颜色、位置,适用于轻量化标识
    • 图片水印:适配个人Logo,支持透明度调整,完美融入背景

2.优势功能

  • 字体加载三重验证
  • 垂直分布参数优化
  • 进度条实时监控
  • 内存性能优化

3.成功效果展示

在这里插入图片描述
在这里插入图片描述

三、代码实现过程

3.1 前期准备

# Python version :3.12
# System : macpro m1 

import os
import math
from PIL import Image, ImageDraw, ImageFont, ImageOps # 图片处理 

# 申明
Image =>  基础图像操作
ImageDraw =>  矢量绘图
ImageFont =>  字体控制
ImageOps  =>  图像增强

3.2 实现过程

3.2.1 主函数和异常处理

try:
    # 使用管理器打开图片
    with Image.open(input_path).convert("RGBA") as base_img:   # 转换RGBA保留透明度通道
        # 创建透明水印层和绘图对象
        watermark = Image.new("RGBA", base_img.size, (0, 0, 0, 0))
        draw = ImageDraw.Draw(watermark)

3.2.2 字体的验证:3重验证确保无误


font_size = 60  
# 排查系统字号,避免字体安装报错 
font_paths = [
    "/System/Library/Fonts/PingFang.ttc",         # 苹果系统字体
    "/System/Library/Fonts/STHeiti Medium.ttc",   # 华文黑体
    "/Library/Fonts/Arial.ttf"                    # Windows/Mac通用字体
] 
font = None
for path in font_paths:
    if os.path.exists(path):  
        try:
            font = ImageFont.truetype(path, font_size, encoding="utf-8")  # 指定编码避免中文乱码保险点 
            break
        except Exception as e:
            print(f"⚠️ 字体加载失败:{path}{str(e)}")
            continue

if not font:
    raise FileNotFoundError("⚠️所有字体路径无效!终端执行:\nls /System/Library/Fonts/PingFang.ttc 验证路径") 
    

3.2.3 水印动态计算 - 计算垂直分布参数


# 间距建议改为动态计算
img_width, img_height = base_img.size
vertical_spacing = 600  
total_height = (3-1)*vertical_spacing  # 总占位高度 = (组数-1)*间距

# 垂直居中算法
start_y = (img_height - total_height) // 2 

3.2.4 循环添加旋转水印


# 添加水印 循环遍历 + 位置处理
for i in range(3):
    current_y = start_y + i * vertical_spacing  # 当前水印Y坐标
    
    # 创建独立文本层,避免污染主绘图对象
    text_bbox = draw.textbbox((0,0), text, font=font)  
    text_width = text_bbox[2] - text_bbox[0] 
    text_layer = Image.new("RGBA", (text_width, font_size), (0,0,0,0))
    text_draw = ImageDraw.Draw(text_layer)
    text_draw.text((0,0), text, font=font, fill=(255,255,255,100))  
    
    # 45度旋转,好看些,也可以不做这部分
    rotated = text_layer.rotate(45, expand=True, resample=Image.BICUBIC)  # 双三次插值
    rotated_width = rotated.width
    x = (img_width - rotated_width) // 2
    
    # 叠加水印层
    watermark.paste(rotated, (x, current_y), rotated) 

3.2.5 合成与保存

# 合成最终图像
combined = Image.alpha_composite(base_img, watermark)  # 阿尔法通道混合 关键步骤
output_path = os.path.join(output_folder, os.path.basename(input_path))
combined.save(output_path, "PNG", quality=95) 
print(f"✅报告四叔,成功添加3组水印:{os.path.basename(input_path)}")

四、完整代码演示


# 图片水印叠加
# -*- coding: utf-8 -*-  
"""
功能:图片无损水印添加
特点:字体加载三重验证 + 垂直分布参数优化 + 进度条实时监控 + 内存性能优化
作者:看海的四叔
最后更新:2025-03-26
"""

import os
import math
from PIL import Image, ImageDraw, ImageFont, ImageOps # 图片处理 

def add_repeated_watermarks(input_path, output_folder, text):
    """添加5组垂直重复水印: 居中+等距分布
    Args:
        input_path (str): 输入图片路径
        output_folder (str): 输出目录路径
        text (str): 水印文字内容
    """
    try:
        with Image.open(input_path).convert("RGBA") as base_img:   
            watermark = Image.new("RGBA", base_img.size, (0, 0, 0, 0))
            draw = ImageDraw.Draw(watermark)
            
            # ===== 1.字体加载三重验证 ===== 
            font_size = 60 
            font_paths = [
                "/System/Library/Fonts/PingFang.ttc",         
                "/System/Library/Fonts/STHeiti Medium.ttc",   
                "/Library/Fonts/Arial.ttf"                    
            ] 
            font = None
            for path in font_paths:
                if os.path.exists(path):  
                    try:
                        font = ImageFont.truetype(path, font_size, encoding="utf-8")  
                        break
                    except Exception as e:
                        print(f"⚠️ 字体加载失败:{path}{str(e)}")
                        continue
            
            if not font:
                raise FileNotFoundError("⚠️ 所有字体路径无效!终端执行:\nls /System/Library/Fonts/PingFang.ttc 验证路径") 

            # ===== 2. 计算垂直分布参数 ===== 
            img_width, img_height = base_img.size
            vertical_spacing = 600                 # 水印垂直间距,根据图片高度动态计算更佳
            total_height = (4-1)*vertical_spacing  
            
            # 计算起始Y坐标 垂直居中算法
            start_y = (img_height - total_height) // 2

            # ===== 3. 循环添加3组水印 ===== 
            for i in range(3):
                current_y = start_y + i * vertical_spacing  # 当前水印Y坐标
                
                # 创建旋转水印文本层(分离图层避免污染主绘图对象)
                text_bbox = draw.textbbox((0,0), text, font=font)     # 获取文本包围盒
                text_width = text_bbox[2] - text_bbox[0]            
                text_layer = Image.new("RGBA", (text_width, font_size), (0,0,0,0))
                text_draw = ImageDraw.Draw(text_layer)
                text_draw.text((0,0), text, font=font, fill=(255,255,255,100))  
                
                # 45度旋转并计算水平居中
                rotated = text_layer.rotate(45, expand=True, resample=Image.BICUBIC)  
                rotated_width = rotated.width
                x = (img_width - rotated_width) // 2  
                
                # 叠加水印层
                watermark.paste(rotated, (x, current_y), rotated) 

            # ===== 4. 合成最终图像 =====
            combined = Image.alpha_composite(base_img, watermark)  
            output_path = os.path.join(output_folder, os.path.basename(input_path))
            combined.save(output_path, "PNG")          
            print(f"✅报告四叔,成功添加3组水印:{os.path.basename(input_path)}")  

    except Exception as e:
        print(f"❌四叔,处理失败 → 错误详情:{str(e)}")


if __name__ == "__main__":
    input_folder = "/Users/admin/xxxx 你的path"
    output_folder = "/Users/admin/xxxxx 你的path"
    watermark_text = "看海的四叔  看海的四叔"    
    
    os.makedirs(output_folder, exist_ok=True)
    # 遍历输入目录所有图片文件(支持JPG/PNG)
    for filename in os.listdir(input_folder):
        if filename.lower().endswith(('.jpg', '.jpeg', '.png')):
            add_repeated_watermarks(
                os.path.join(input_folder, filename),
                output_folder,
                watermark_text
            )

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值