【Python】PIL给图片添加水印最全代码解释

news2024/11/23 8:10:42

给图片添加水印

以下是一个添加水印的方法,你可以将其放在一个单独的 Python 文件中,然后在需要添加水印的地方调用该方法即可:

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)

该方法接受五个参数:

  • image_path:需要添加水印的图片路径;
  • text:水印文本;
  • font_path:字体文件路径;
  • font_size:字体大小,默认为 40;
  • fill:水印颜色,默认为白色半透明。

你可以根据需要修改这些参数。

使用该方法的示例代码如下:

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

该代码会在 image.jpg 图片中添加一个水印,水印文本为 Hello, world!,字体为 simsun.ttc,字体大小为 50。

fill参数解释:

fill 参数指定了水印的颜色。在 PIL 库中,颜色是以一个四元组来表示的,四元组中的四个值分别代表红、绿、蓝和透明度,取值范围为 0 到 255。例如,(255, 0, 0, 128) 表示红色半透明。

add_watermark() 方法中,我们将默认的 fill 参数设置为 (255, 255, 255, 128),即白色半透明,这样可以让水印不会完全遮挡住原图。你可以根据需要修改该参数,例如将水印颜色修改为红色,可以将 fill 参数修改为 (255, 0, 0, 128)

textbbox参数解释

textbbox() 方法是 Pillow 库中 ImageDraw 模块提供的一个函数,用于计算绘制文本所需的矩形框的大小。该方法的语法如下:

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

其中,各参数的含义如下:

  • xy:一个二元组 (x, y),表示文本的起始位置,即文本框的左上角坐标。
  • text:表示要绘制的文本内容。
  • font:表示字体对象,可以使用 ImageFont.truetype() 方法创建。
  • spacing:表示行与行之间的间距,默认为 0。
  • align:表示文本的水平对齐方式,可以是 'left''center''right'

textbbox() 方法会根据文本内容、字体和起始位置等信息计算出文本框的大小,返回一个四元组 (x0, y0, x1, y1),表示文本框的左上角和右下角坐标。其中,(x0, y0) 表示文本框的左上角坐标,(x1, y1) 表示文本框的右下角坐标。

在绘制文本时,我们可以使用 textbbox() 方法先计算出文本框的大小,然后根据文本框的大小来计算文本的位置,从而确保文本在图片中居中或居左等对齐方式。

异常处理

warning提示:

DeprecationWarning: textsize is deprecated and will be removed in Pillow 10 (2023-07-01). Use textbbox or textlength instead. text_width, text_height = draw.textsize(text, font=font)

解决方法:

这个警告是因为在 Pillow 库的未来版本中,textsize() 方法将被弃用,建议使用 textbbox()textlength() 方法代替。因此,在编写代码时,我们应该尽可能避免使用 textsize() 方法。

根据警告信息,你可以将代码中的 textsize() 方法替换为 textbbox()textlength() 方法。例如,将上面的代码修改为:

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)

在上面的代码中,我们使用 textbbox() 方法来计算文本的宽度和高度,然后根据图片大小和文本大小来计算出文本在图片中的位置,最后将文本绘制到图片上。这样可以避免使用 textsize() 方法时出现的警告。

异常draw.textbbox

text_width, text_height = draw.textbbox((10, 10), text, font=font)代码这个地方抛出异常Error: too many values to unpack (expected 2)

这个错误通常是由于 textbbox() 方法返回的四元组 (x0, y0, x1, y1) 与期望的二元组 (text_width, text_height) 不匹配引起的。

要解决这个问题,您可以使用四元组中的左上角坐标 (x0, y0) 和右下角坐标 (x1, y1) 计算文本的宽度和高度,例如:

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

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

这里,我们使用 bbox[2] - bbox[0] 计算文本的宽度,使用 bbox[3] - bbox[1] 计算文本的高度。这样,就可以将计算出的宽度和高度存储在 text_widthtext_height 变量中,以供后续使用。

请注意,在使用 textbbox() 方法时,返回的四元组中的值的顺序是 (x0, y0, x1, y1),因此,您需要根据需要来提取相应的值。

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)
中文显示异常

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

调用方式:

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jYNI8pkj-1684290601180)(Excel与PIL.assets/image-20230517102532955.png)]

我们期待图片中间有:测试!,水印显示在图片上,实际结果我们已经看到,看来还是哪里有问题;

修改中文字体库引用就可以了

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)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HzCecq1L-1684290601181)(Excel与PIL.assets/image-20230517102808833.png)]

刚才我用了:C:\Windows\Fonts\微软雅黑\msyh.ttc这个路径,跟大家提一下这是Windows系统字体默认的存储位置;

到这里就实现给图片添加水印的基本操作了,赶紧动手试试吧;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/535545.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis 经典面试题合合集详解

❤ 作者主页:欢迎来到我的技术博客😎 ❀ 个人介绍:大家好,本人热衷于Java后端开发,欢迎来交流学习哦!( ̄▽ ̄)~* 🍊 如果文章对您有帮助,记得关注、点赞、收藏、…

Cy7-COOH近红外菁染料CAS号1628790-40-8星戈瑞

CY7-COOH是一种红外荧光染料,其最大激发和发射波长分别为750nm和773nm。这种荧光染料分子具有较高的光稳定性和化学稳定性,可以在细胞和组织中长时间稳定地发光,因此应用于生命科学领域的荧光显微镜成像、生物传感和分析等方面。 产品名称&a…

深眸科技|工业3D视觉创新崛起,与2D视觉融合创建更高效解决方案

近年来,伴随着人工智能技术的进步,行业应用需求的提升,机器视觉技术持续升级。由于2D视觉技术难以满足精密制造行业不断提高的精度需求,能够更全面、更多维了解产品信息的3D视觉技术逐渐火热,并掀起浪潮。 据GGII数据…

西米支付:数字人民币接口来了!实时清算至数字人民币钱包。

1. 产品概述 什么是数字人民币? 是由中国人民银行发行的数字形式的法定货币,由指定运营机构参与运营,与实物人民 币等价,具有价值特征和法偿性,是一种零售型央行数字货币,也是未来主流支付方式之一&#…

楠姐技术漫话:图计算的那些事 | 京东云技术团队

不知道大家在平时的工作中 有没有听说过“图计算”这个名词 但大家一定在各工作汇报,技术分享中听说过“智能化”,“人工智能”这样的字眼 而我们今天要唠的这个图计算 就是人工智能领域内近几年炙手可热的前沿宠儿 也是我们风控反欺诈中常用的“大杀…

不会Elasticsearch标准查询语句,如何分析数仓数据?

1 Elasticsearch的查询语句 ES中提供了一种强大的检索数据方式,这种检索方式称之为Query DSL,Query DSL是利用Rest API传递JSON格式的请求体(Request Body)数据与ES进行交互,这种方式的丰富查询语法让ES检索变得更强大,更简洁。 1.1 查询预发 # GET /…

ChatGPT中文使用手册

简要介绍: First:什么是ChatGPT? ChatGPT是由OpenAI训练的一款大型语言模型,最新版为GPT3.5(公开版)和GPT4.0(PLUS会员版本) 它能够生成类似于人类写作的文本。您只需要给出提示或提出问题&…

ChatGPT实现游戏 NPC 对话

游戏 NPC 对话 玩游戏的一个必要过程,就是和 NPC 对话,领取任务,获取线索。有趣的游戏,会根据用户和 NPC 交流时的不同选择,触发不同剧情走向。甚至多个 NPC 之间还能有罕见的隐藏剧情,等待用户发掘。可以…

《PyTorch高级机器学习实战》包邮送书三本

目录 前言书籍目录抽奖方式 前言 随着人工智能和机器学习的蓬勃发展,相关算法和技术已经广泛运用到诸多行业,大量的研究者和各行业人员也投入机器学习的研究与开发中。 掌握高级机器学习算法原理,并能够根据不同情况实现灵活运用&#xff0…

NineData:高效高质量的Redis可视化管理工具

Redis 是一个内存数据结构存储系统,它被广泛用于缓存、队列、实时分析等多种应用场景中,目前已经成为 Key-value 数据存储系统中的佼佼者,根据 DB-Engine 网站提供的最新数据,Redis 在 Key-value stores 类别中排名第一&#xff0…

Dynamics 365 DevOps CI/CD之Solution

CI/CD到了Soution就没太多可说的了,按部就班配置就行,我选择的工具是Power DevOps Tool 1,首先下载工具,然后设置连接字符串去连环境,连接字符串还是用ClientSecret的形式 2,当然导出前还是要发布下自定义的…

小程序分包

分包加载的介绍 大部分小程序都会由某几个功能组成,通常这几个功能之间是独立的,但会依赖一些公共的逻辑,并且这些功能通常会对应某几个独立的页面。那么小程序代码的打包,大可不必一定要打成一个,可以按照功能的划分&…

c/c++ 宏定义里的#和##

工作中如果是c开发的话&#xff0c;经常会用到宏定义&#xff0c;而宏定义中的#和##也会时不时遇到&#xff0c;今天分享这两个符号的作用。 1&#xff0c;# -- 转换成字符串 直接看例子&#xff1a; #include <stdio.h> #include <stdlib.h>#define VAL2STR(VA…

vue非单文件组件的使用方法

标准化开发时的嵌套&#xff1a; 在实际开发中&#xff0c;通常会创建一个 APP 组件作为根组件&#xff0c;由这个根组件去管理其它的组件&#xff0c;而 Vue 实例只需要管理这个 APP 组件就行了。 <!DOCTYPE html> <html><head><meta charset"utf…

springboot+java办公用品租赁领用管理信息系统

将系统权限按管理员和员工这两类涉及员工划分。 (a) 管理员&#xff1b;管理员使用本系统涉到的功能主要有&#xff1a;个人中心、员工管理、办公用品管理、领用申请管理、采购申请管理、物品分类管理、系统管理等功能。 (b)员工进入系统前台可以实现办公用品管理、领用申请管理…

TimerResolution.exe

TimerResolution.exe是一款常用的Windows实用程序,用于调整系统计时器的分辨率。它提供了一种简便的方法,让用户能够更精确地控制计时器的运行方式,从而改善系统的性能和响应时间。无论是进行游戏、音频处理还是其他需要精确计时的任务,TimerResolution.exe都能提供极大的帮…

【PR】来制作视频进度条吧~

【PR】来制作视频进度条吧~ 制作进度条制作分割线及标题分割线标题其他 为啥视频要有进度条~ 方便观众回看和定位&#xff1a;添加进度条可以让观众在观看视频时随时了解视频播放的进度&#xff0c;也方便观众在需要回看或者查找某一段内容时能够更加精准地定位。 提高观看体验…

当电脑回收站图标不见后,这4种方法帮你快速恢复

我们都知道&#xff0c;在电脑上删除文件时&#xff0c;这些文件多数都会先停留在回收站中。当我们后悔删除这些文件时&#xff0c;往往可以通过回收站还原&#xff0c;可是有些小伙伴却发现自己的电脑回收站不见了&#xff0c;这无疑给我们的回收站文件恢复工作带来不便&#…

NXP MCUXPresso - 操作整理

文章目录 NXP MCUXPresso - 操作整理概念如何在工程中全局搜索文本?在一个编译配置中, 如何排除一些不要的内容?END NXP MCUXPresso - 操作整理 概念 在尝试迁移 openpnp - Smoothieware project 从gcc命令行 MRI调试方式 到NXP MCUXpresso工程. 这个IDE还是蛮喜欢的, 细节…

人工智能算法|K均值聚类算法Python实现

01、算法说明 K均值聚类算法是一种简单的迭代型聚类算法&#xff0c;采用距离作为相似性指标&#xff0c;从而发现给定数据集中的K个类&#xff0c;且每个类有一个聚类中心&#xff0c;即质心&#xff0c;每个类的质心是根据类中所有值的均值得到。对于给定的一个包含n个d维数据…