Pillow库(PIL)使用入门教程
Pillow 提供了非常强大的图像处理功能,它能够很轻松地完成一些图像处理任务。与 Python 的其他图像处理库相比(OpenCV、Scikit-image 等),Pillow 库简单易用,非常适合初学者学习。
相关资源:
- Python Pillow 官方文档:Pillow (PIL Fork) 10.2.0.dev0 documentation
- 本套教程的图片资源下载:百度网盘 请输入提取码(提取码:n1v2)
Pillow 库(有时也称 PIL 库) 是 Python 图像处理的基础库,它是一个免费开源的第三方库,由一群 Python 社区志愿者使用 Python 语言开发而成。
Pillow 提供了非常强大的图像处理功能,它能够很轻松地完成一些图像处理任务。与 Python 的其他图像处理库相比(OpenCV、Scikit-image 等),Pillow 库简单易用,非常适合初学者学习。
Pillow 库提供了非常丰富的功能,主要有以下几点:
- Pillow 库能够很轻松的读取和保存各种格式的图片;
- Pillow 库提供了简洁易用的 API 接口,可以让您轻松地完成许多图像处理任务;
- Pillow 库能够配合 GUI(图形用户界面) 软件包 Tkinter 一起使用;
- Pillow 库中的 Image 对象能够与 NumPy ndarray 数组实现相互转换。
丰富功能的实现得益于 Pillow 提供了众多的模块。在 Pillow 库中有二十多个模块,比如 Image 图像处理模块、ImageFont 添加文本模块、ImageColor 颜色处理模块、ImageDraw 绘图模块等等,每个模块各自实现了不同的功能,同时模块之间又可以互相配合。
一、Pillow是什么
PIL( Python Imaging Library)是 Python 的第三方图像处理库,由于其功能丰富,API 简洁易用,因此深受好评。
自 2011 年以来,由于 PIL 库更新缓慢,目前仅支持 Python 2.7 版本,这明显无法满足 Python3 版本的使用需求。于是一群 Python 社区的志愿者(主要贡献者:Alex Clark 和 Contributors)在 PIL 库的基础上开发了一个支持 Python3 版本的图像处理库,它就是 Pillow。
Pillow 不仅是 PIL 库的“复制版”,而且它又在 PIL 库的基础上增加了许多新的特性。Pillow 发展至今,已经成为了比 PIL 更具活力的图像处理库。
Pillow 的初衷只是想作为 PIL 库的分支和补充,如今它已是“青出于蓝而胜于蓝”。
除了 PIL 和 Pillow 库之外,Python 还提供了一些其他图像处理库:
Scikit-image:一款基于 scipy 科学计算的图像处理软件包,以数组的形式对图像进行处理;
OpenCV:其实是一个 C++ 图像处理库,不过它提供了 Python 语言的接口。
Pillow 是 Python 中较为基础的图像处理库,主要用于图像的基本处理,比如裁剪图像、调整图像大小和图像颜色处理等。与 Pillow 相比,OpenCV 和 Scikit-image 的功能更为丰富,所以使用起来也更为复杂,主要应用于机器视觉、图像分析等领域,比如众所周知的“人脸识别”应用。
二、Pillow库特点
Pillow库作为图像处理的常用库,主要有以下三大特点:
1. 支持广泛的文件格式
Pillow 支持广泛的图像格式,比如 "jpeg","png","bmp","gif","ppm","tiff" 等。同时,它也支持图像格式之间的相互转换。总之, Pillow 几乎能够处理任何格式的图像。
2. 提供了丰富的功能
Pillow 提供了丰富的图像处理功能,可概括为两个方面:
- 图像归档
- 图像处理
图像归档,包括创建缩略图、生成预览图像、图像批量处理等;
而图像处理,则包括调整图像大小、裁剪图像、像素点处理、添加滤镜、图像颜色处理等。
3. 配合GUI工具使用
Pillow 库可以配合 Python GUI(图形用户界面)工具 Tkinter 一起使用。
除上述特点之外,Pillow 库还能实现一些较为复杂的图像处理操作,比如给图像添加水印、合成 GIF 动态效果图等等。
二、Pillow的下载与安装
Pillow 安装非常简单和方便,有三种安装途径,分别是:
- pip包管理器安装
- 二进制包安装
- Anaconda安装
下面对上述安装方式做简单介绍。
注意,PIL 库与 Pillow 库不允许在同一环境中共存,如果您之前安装了 PIL 库,请卸载后,再安装 Pillow。
1. pip包管理器安装
通过 Python 包管理器 pip 来安装 Pillow 是最简单、轻量级的一种安装方式,并且这种方法适用于任何平台。只需执行以下命令即可:
pip install pillow
2. 二进制包安装
通过 Python PyPi 第三方库官网(Pillow · PyPI)下载与平台系统相对应的版本
下载完成后,进入下载文件的所在位置,然后直接使用 pip 命令来安装 .whl 文件即可,如下所示:
pip install + whl文件名
还可以使用Anaconda安装,Anaconda自带很多安装完的软件包,其中就包含Pillow,因此无需重新安装。
三、Pillow创建Image对象
Image类是Pillow中最重要的类,该类在被定义在和其同名的Image模块中。
使用下列导包方式引入Image模块。
使用Image类可以实例化一个Image对象,通过调用该对象的一系列属性和方法对图像进行处理。Pillow提供了两种创建Image实例对象的方法。
1. open()
使用Image类的open()方法,可以创建一个Image对象,语法格式如下:
im = Image.open(fp, mode = "r")
参数说明:
- fp:即 filepath 的缩写,表示文件路径,字符串格式;
- mode:可选参数,若出现该参数,则必须设置为 "r",否则会引发 ValueError 异常。
示例如下:
from PIL import Image
#打开一图片文件
im = Image.open("C:/Users/Administrator/Desktop/1.jpeg")
#要显示图像需要调用show()方法
im.show()
图像显示如下:

2. new()
使用Image类提供的new()方法可以创建一个新的Image对象,语法格式如下:
im = Image.new(mode, size, color)
参数说明如下:
- mode:图像模式,字符串参数,比如RGB(真彩图像)、L(灰度图像)、CMYK(色彩图打印模式)等;
- size:图像大小,元组参数(width, height)代表图像的像素大小;
- color:图片颜色,默认值为 0 表示黑色,参数值支持(R,G,B)三元组数字格式、颜色的十六进制值以及颜色英文单词。
示例如下:
#使用颜色的十六进制格式
im_1 = Image.new(mode = 'RGB', (260, 100), color = "#ff0000")
im_1.show()
输出图像是一个纯红色的图。
四、Pillow Image对象属性
Image对象有一个常用的基本属性,这些属性能帮助我们了解图片的基本信息,下面对这些属性做简单的讲解。
1. size:查看图像的尺寸
from PIL import Image
im = Image.open("1.jpeg")
print(im)
print(im.size)
print(im.width)
print(im.height)
2. format:查看图片的格式
from PIL import Image
im = Image.open("C:/Users/Administrator/Desktop/1.png")
print("图像的格式:", im.format)
输出结果:
图像的格式: PNG
3. readonly:图片是否为只读
from PIL import Image
im = Image.open("C:/Users/Administrator/Desktop/c-net.png")
print("图像是否为只读:", im.readonly)
该属性的 返回为 0 或者 1,分别对应着是和否,输出结果如下:
图像是否为只读: 1
4. info:查看图片相关信息
from PIL import Image
im = Image.open("C:/Users/Administrator/Desktop/c-net.png")
#包括了每英寸像素点大小和截图软件信息
print("图像信息:", im.info)
该属性的返回值为字典格式,输出结果如下:
图像信息: {'dpi': (96, 96), 'Software': 'Snipaste'}
5. mode:图像模式
from PIL import Image
im = Image.open("C:/Users/Administrator/Desktop/c-net.png")
print("图像模式信息:", im.mode)
输出结果:
图像的模式: RGBA
上述涉及了许多图片模式的名称,比如 RGB、RGBA 等,下面对常用的图片模式做简单的总结,如下表所示:

五、Pillow图片格式转换
Pillow库支持多种图片格式,可以直接使用open()方法来读取图片,并且无须考虑图片是何种类型。同时,Pillow 能够很轻松地实现图片格式之间的转换。
图片格式之间的转换主要有以下两种方法,下面分别对它们进行了介绍:
1. save()
顾名思义,save() 方法用于保存图像,当不指定文件格式时,它会以默认的图片格式来存储;如果指定图片格式,则会以指定的格式存储图片。save() 的语法格式如下:
Image.save(fp, format = None)
参数说明如下:
- fp:图片的存储路径,包含图片的名称、字符串格式
- format:可选参数,可以指定图片的格式
示例如下:
from PIL import Image
im = Image.open("C:/Users/Administrator/Desktop/1.png")
im.save('C:/Users/Administrator/Desktop/1.bmp')
此时会保存一个bmp格式的图片。
2. convert() + save()
注意,并非所有的图片格式都可以用 save() 方法转换完成,比如将 PNG 格式的图片保存为 JPG 格式,如果直接使用 save() 方法就会出现以下错误:
from PIL import Image
im = Image.open("C:/Users/Administrator/Desktop/c-net.png")
im.save('C:/Users/Administrator/Desktop/c.biancheng.net.jpg')
错误信息如下所示:
#系统错误,RGBA不能作为JPEG图片的模式
OSError: cannot write mode RGBA as JPEG
引发错误的原因是由于 PNG 和 JPG 图像模式不一致导致的。其中 PNG 是四通道 RGBA 模式,即红色、绿色、蓝色、Alpha 透明色;JPG 是三通道 RGB 模式。因此要想实现图片格式的转换,就要将 PNG 转变为三通道 RGB 模式
Image 类提供的 convert() 方法可以实现图像模式的转换。该函数提供了多个参数,比如 mode、matrix、dither 等,其中最关键的参数是 mode,其余参数无须关心。语法格式如下:
convert(mode, params**)
- mode:指的是要转换成的图像模式;
- params:其他可选参数。
修改后的代码如下所示:
from PIL import Image
im = Image.open("C:/Users/Administrator/Desktop/c-net.png")
#此时返回一个新的image图像,转换图片模式
image = im.convert('RGB')
#调用save()保存
im.save('C:/Users/Administrator/Desktop/c.biancheng.net.jpg')
六、 Pillow图像缩放操作
在图像处理过程中经常会遇到缩小或放大图像的情况,Image 类提供的 resize() 方法能够实现任意缩小和放大图像。
resize() 函数的语法格式如下:
resize(size, resample = image.BICUBIC, box = None, reducing_gap = None)
参数说明:
- size:元组参数 (width,height),图片缩放后的尺寸;
- resample:可选参数,指图像重采样滤波器,与 thumbnail() 的 resample 参数类似,默认为 Image.BICUBIC;
- box:对指定图片区域进行缩放,box 的参数值是长度为 4 的像素坐标元组,即 (左,上,右,下)。注意,被指定的区域必须在原图的范围内,如果超出范围就会报错。当不传该参数时,默认对整个原图进行缩放;
- reducing_gap:可选参数,浮点参数值,用于优化图片的缩放效果,常用参数值有 3.0 和 5.0。
注意,resize() 会返回一个新的 image 对象。下面是一组对图像进行放大操的示例:
from PIL import Image
im = Image.open("C:/Users/Administrator/Desktop/c-net.png")
try:
#放大图片
image = im.resize((550,260))
#将新图像保存至桌面
image.save("C:/Users/Administrator/Desktop/放大图像.png")
print("查看新图像的尺寸", img.size)
expect IOError:
print("放大图像失败")
输出结果:
查看新图像的尺寸 (550, 260)
可以看到图像已经放大成功。


对图片的局部位置进行放大:
from PIL import Image
im = Image.open("C:/Users/Administrator/Desktop/c-net.png")
try:
#选择放大的局部位置,并选择图片重采样方式
#box四元组指的是像素坐标(左,上,右,下)
#(0, 0,120, 180),表示以原图的左上角为原点,选择宽和高分别为(120,180)的图像区域
image = im.resize((550,260), reshape = Image.LANCZOS, box = (0, 0, 120, 180))
image.show()
#保存
image.save("C:/Users/Administrator/Desktop/放大图像.png")
print("查看新图像的尺寸", img.size)
expect IOError:
print("放大失败")
放大成功:

七、Pillow图像分离与合并
我们知道,图像(指数字图像)由许多像素点组成,像素是组成图像的基本单位,而每一个像素点又可以使用不同的颜色,最终呈现出了绚丽多彩的图像。在《第四部分 Pillow Image对象属性》一节,我们介绍一些图片模式,它们的本质就是图片呈现颜色时需要遵循的规则,比如 RGB、RGBA、CYMK 等,而图像的分离与合并,指的就是图像颜色的分离和合并。
Image类提供了用于分离图像和合并图像的方法split() 和 merge() 方法,通常情况下,这两个方法会一起使用。
1. split()
split的使用方法比较简单,用来分离颜色通道。我们用它来处理蝴蝶图片。

代码如下所示:
im = Image.open("C:/Users/Administrator/Desktop/1.jpg")
#修改图像大小,以适应图像处理
image = im.resize((450,400))
image.save("C:/Users/Administrator/Desktop/2.jpg")
#分离颜色通道,产生三个Image对象
r, g,b =image.split()
r.show()
g.show()
b.show()
2. merge()
Image类提供的merge()方法可以实现图片的合并操作。注意,图像合并,可以是单个图像合并,也可以合并两个以上的图像。
merge方法的语法格式如下:
Image.merge(mode, hands)
参数说明如下:
- mode:指定输出图片的模式。
- bands:参数类型为元组或者列表序列,其元素值是组成图像的颜色通道,比如 RGB 分别代表三种颜色通道,可以表示为 (r,g,b)。
注意,该函数会返回一个新的Image对象。
下面对图像合并的两种类型分别进行介绍。
一. 单个图像的合并指的是将颜色通道进行重新组合,从而得到不一样的图片效果,代码如下所示:
from PIL import Image
im = Image.open("C:/Users/Administrator/Desktop/1.jpg")
#修改图像大小,以适应图像处理
image = im.resize((450,400))
image.save("C:/Users/Administrator/Desktop/2.jpg")
#分离颜色通道,产生三个Image对象
r, g,b =image.split()
#重新组合颜色通道,返回新的Image对象
image_merge = Image.merge('RGB', (b, g, r))
image_merge.show()
#保存图像至桌面
image_merge.save("C:/Users/Administrator/Desktop/3.jpg")
新合成的图像如图所示:

两张图片的合成操作也不复杂,但是要求两张图片的模式、图像大小必须要保持一致,否则不能合并。因此,对于那些模式、大小不同的图片要进行预处理。
下面我们将蝴蝶图与向日葵图进行合并,向日葵原图如下:

示例代码如下:
from PIL import Image
#打开图2.jpg
im_1 = Image.open("C:/Users/Administrator/Desktop/2.jpg")
im_2 = Image.open("C:/Users/Administrator/Desktop/向日葵.jpg")
#因为两种图片的图片格式一致,所以仅需要处理图片的大小,让它们保持一致
#让 im_2 的图像尺寸与 im_1 一致,注意此处新生成了 Image 对象
image = im_2.resize(im_1.size)
#接下来,对图像进行颜色分离操作
r1, g1, b1 =im_1.split()
r2, g2, b2 =image.split()
#合并图像
im_3 = Image.merge('RGB', [r2, g1, b2])
im_3.show()
im_3.save("C:/Users/Administrator/Desktop/合成.jpg")
预览图像的合成结果:

3. blend()混合图片
Image 类也提供了 blend() 方法来混合 RGBA 模式的图片(PNG 格式),函数的语法格式如下:
Image.blend(image1, image1, alpha)
参数说明如下:
- image1,image2:表示两个 Image 对象。
- alpha:表示透明度,取值范围为 0 到 1,当取值为 0 时,输出图像相当于 image1 的拷贝,而取值为 1 时,则是 image2 的拷贝,只有当取值为 0.5 时,才为两个图像的中合。因此改值的大小决定了两个图像的混合程度。
与RGB 模式相比,RGBA 在 RGB 的基础上增加了透明度,通过 Alpha 取值来决定两个图像的混合程度。示例如下:
"""
混合rgba模式的图像
"""
im1 = Image.open("C:/Users/Administrator/Desktop/c-net.png")
image = Image.open("C:/Users/Administrator/Desktop/心形函数图像.png")
im2 = image.resize(im1.size)
def blend_im(im1, im2):
#设置 alpha 为0.5
Image.blend(im1, im2, 0.5).save("C:/Users/Administrator/Desktop/C语言中文网.png")
#调用函数
blend_im(im1, im2)
输出结果如下:

八、Pillow图像裁剪、复制、粘贴操作
图像的剪裁、复制、粘贴是图像处理过程中经常使用的基本操作,Pillow Image 类提供了简单、易用的 API 接口,能够帮助您快速实现这些简单的图像处理操作。
1. 图像裁剪操作
Image类提供的crop()函数允许我们以矩形区域的方式对原图像进行裁剪,函数的语法格式如下:
crop(box = None)
box:表示裁剪区域,默认为None,表示拷贝原图像
注意:box是一个有四个数字的元组参数(x_左上,y_左下,x1_右上,y1_右下),分别表示被裁剪矩形区域的左上角x、y坐标和右下角x、y坐标。默认 (0,0) 表示坐标原点,宽度的方向为 x 轴,高度的方向为 y 轴,每个像素点代表一个单位。
crop() 函数会返回一个 Image 对象,使用示例如下:
"""
裁剪图像
"""
im = Image.open("C:/Users/Administrator/Desktop/C语言中文网.png")
box = (0, 0, 200, 100)
im_crop = im.crop(box)
im_crop.show()
输出图像显示如下:

最终,在原图的基础上裁剪出一张像素为200*100的图像。
2. 图像拷贝和粘贴
拷贝、粘贴操作几乎是成对出现的,Image 类提供了 copy() 和 paste() 方法来实现图像的复制和粘贴。其中复制操作(即 copy() 方法)比较简单,下面主要介绍 paste() 粘贴方法,语法格式如下所示:
paste(image, box = None, mask = None)
该函数的作用是将一张图片粘贴至另一张图片中。注意,粘贴后的图片模式将自动保持一致,不需要进行额外的转换。参数说明如下:
- image:指被粘贴的图片。
- box:指定图片被粘贴的位置或者区域,其参数值是长度为2或者4的元组序列,长度为 2 时,表示具体的某一点 (x,y);长度为 4 则表示图片粘贴的区域,此时区域的大小必须要和被粘贴的图像大小保持一致。
- mask:可选参数,为图片增加蒙版效果。
下面复制一张原图像的副本,对副本进行裁剪、粘贴操作,代码如下所示:
im = Image.open("C:/Users/Administrator/Desktop/C语言中文网.png")
#复制一张图片副本
im_copy = im.copy()
#对副本进行裁剪
im_crop = im.crop((0, 0, 200, 100))
#创建一个新的图像作为蒙版,L模式,单颜色值
img_new = Image.new('L', (200, 100), 200)
#将裁剪后的副本粘贴至副本图像上,并添加蒙版
im_crop.paste(im_crop, (100, 100, 300, 200), mask = image_new)
#显示粘贴后的图像
im_crop.show()
输出的显示结果,如下所示:

九、Pillow图像几何变换
图像的几何变换主要包含图像翻转、图像旋转和图像变换操作,Image 类提供了处理这些操作的函数 transpose()、rotate() 和 transform(),下面分别对它们进行讲解。
1. transpose()翻转操作
该函数可以实现图像的垂直、水平翻转,语法格式如下:
Image.transpose(method)
method参数决定了图片要如何翻转,参考值如下:
- Image.FLIP_LEFT_RIGHT:左右水平翻转;
- Image.FLIP_TOP_BOTTOM:上下垂直翻转;
- Image.ROTATE_90:图像旋转 90 度;
- Image.ROTATE_180:图像旋转 180 度;
- Image.ROTATE_270:图像旋转 270 度;
- Image.TRANSPOSE:图像转置;
- Image.TRANSVERSE:图像横向翻转。
使用示例如下:
im = Image.open("C:/Users/Administrator/Desktop/c-net.png")
#返回一个新的Image对象
im_out = im.transpose(Image.FLIP_LEFT_RIGHT)
im_out.show()
im_out.save("C:/Users/Administrator/Desktop/水平翻转.png")
图像显示结果,如下所示:

2. rotate()任意角度旋转
当我们把图像旋转任意角度时,可以使用rotate角度,语法格式如下:
Image.rotate(angle, resample = PIL.Image.NEAREST, expand = None, ceter = None,
translate = None, fillcolor = None)
参数说明如下:
- angle:表示任意旋转的角度;
- resample:重采样滤波器,默认为 PIL.Image.NEAREST 最近邻插值方法;
- expand:可选参数,表示是否对图像进行扩展,如果参数值为 True 则扩大输出图像,如果为 False 或者省略,则表示按原图像大小输出;
- center:可选参数,指定旋转中心,参数值是长度为 2 的元组,默认以图像中心进行旋转;
- translate:参数值为二元组,表示对旋转后的图像进行平移,以左上角为原点;
- fillcolor:可选参数,填充颜色,图像旋转后,对图像之外的区域进行填充。
使用示例如下:
im = Image.open("C:/Users/Administrator/Desktop/c-net.png")
#translate的参数值可以为负数,并将旋转图之外的区域填充为绿色
#返回同一个新的Image对象
im_out = im.rotate(45, translate = (0, -25),fillcolor = "green")
im_out.show()
im_out.save("C:/Users/Administrator/Desktop/旋转图像.png")
输出结果:

3. transform()图像变换
该函数能够对图像进行变换操作,通过指定的变换方式,产生一张规定大小的新图像,语法格式如下:
Image.transform(size, method, data = None, resample = 0)
参数说明:
- size:指定新图片的大小;
- method:指定图片的变化方式,比如 Image.EXTENT 表示矩形变换;
- data:该参数用来给变换方式提供所需数据;
- resample:图像重采样滤波器,默认参数值为 PIL.Image.NEAREST。
使用示例如下:
from PIL import Image
im = Image.open("C:/Users/Administrator/Desktop/c-net.png")
#设置图像大小250*250,并根据data的数据截取原图像的区域,生成新的图像
im_out = im.transform((250, 250), Image.EXTENT, data = [0, 0, 30 + im.width//4, im.height//3])
im_out.show()
im_out.save("C:/Users/Administrator/Desktop/变换.png")
输出图像显示如下:

十、Pillow为图片加水印
为图片添加水印能够在一定程度上避免其他人滥用图片,这是保护图片版权的一种有效方式。因此,
当您在微博、或者博客等一些公众平台分享图片的时候,建议您为自己的图片添加一个水印,来证明这张图片属于您。
添加水印的方式的有很多种,比如通过一些图像处理软件,或者手机美图软件都可以实现添加水印的操作,但是这种操作比较复杂,甚至有些软件还不是免费的。
Pillow 库提供了添加水印的方法,操作简单,易学、易用。下面我们讲解如何使用 PIilow 给图片添加水印。
我们知道,水印是附着在原图片上一段文字信息,因此添加水印的过程中会涉及两个问题:
- 第一、如何使文字信息附着在图片上;
- 第二、如何绘制文字信息。
只要解决了这两个问题就可以成功添加水印。Pillow 提供的ImageDraw和ImageFont模块成功解决了上述问题。
1. ImageDraw
PIL.ImageDraw 模块提供了一系列的绘图方法,通过该模块可以创建一个新的图形,或者在现有的图像上再绘制一个图形,从而起到对原图注释和修饰的作用。
下面创建一个 ImageDraw 对象,并对该对象的使用方法做简单介绍:
draw = ImageDraw.Draw(im)
上述方法会返回一个 ImageDraw 对象,参数 im 表示 Image 对象。这里我们可以把 Image 对象理解成画布,通过调用 ImageDraw 对象的一些方法,实现了在画布上绘制出新的图形目的。ImageDraw 对象的常用方法如下表所示:
| 方法 | 说明 |
|---|---|
| text | 在图像上绘制文字 |
| line | 绘制直线、线段 |
| eclipse | 绘制椭圆形 |
| rectangle | 绘制矩形 |
| polygon | 绘制多边形 |
表格中第一个方法 text() 需要与 ImageFont 模块一起使用,在下面会做详细介绍。
绘制矩形图的语法格式如下:
draw.rectangle(xy, fill = None, outline = None)
参数说明如下:
- xy:元组参数值,以图像的左上角为坐标原点,表示矩形图的位置、图形大小的坐标序列,形如 ((x1,y1,x2,y2));
- fill:矩形图的背景填充色;
- outline:矩形图的边框线条颜色。
下面看一组简单的示例:
from PIL import Image, ImageDraw
#创建Image对象,当做背景图
im = Image.new('RGB', (200, 200), color = 'gray')
#创建ImageDraw对象
draw = ImageDraw.Draw(im)
##以左上角为原点,绘制矩形。
#元组坐标序列表示矩形的位置、大小;fill设置填充色为红色,outline设置边框线为黑色
draw.rectangle((50, 100, 100, 150), fill = (255, 0, 0), outline = (0, 0, 0))
#查看原图片
im.show()
#保存图片
im.save("C:/Users/Administrator/Desktop/添加矩形图.png")
图像显示结果如下:

2. ImageFont
PIL.ImagreFont 模块通过加载不同格式的字体文件,从而在图像上绘制出不同类型的文字,比如 TrueType 和 OpenType 类型的字体。
创建字体对象的语法格式如下:
font = ImageFont.truetype(font = '字体文件路径', size = 字体大小)
如果想要在图片上添加文本,还需要使用 ImageDraw.text() 方法,语法格式如下:
d.text((x,y), "text", font, fill)
参数说明如下:
- (x,y):图像左上角为坐标原点,(x,y) 表示添加文本的起始坐标位置;
- text:字符串格式,要添加的文本内容;
- font:ImageFont 对象;
- fill:文本填充颜色。
下面看一组使用示例,如下所示:
from PIL import Image, ImageFont, ImageDraw
#打开图片,返回Image对象
im = Image.open("C:/Users/Administrator/Desktop/c-net.png")
#创建画布对象
draw = ImageDraw.Draw(im)
#加载计算机本地字体文件
font = ImageFont.truetype(font = 'C:/Windows/Fonts/msyh.ttc', size = 36)
#在原图像上添加文本
draw.text(xy = (80,50), text = 'C语言中文网', fill = (255, 0, 0), font = font)
im.show()
im.save("C:/Users/Administrator/Desktop/c.png")
图像显示结果如下:

3. 添加图片水印
通过上述知识的学习,我们对ImageDraw和ImageFont模块有了大体的认识,并且也解决了如何给图片添加水印的两个关键问题。以下示例展示了为图片添加水印的详细过程,代码如下所示:
"""
添加水印(函数式编程)
"""
from PIL import Image, ImageFont, ImageDraw
#加载计算机本地字体文件
font = ImageFont.truetype(font = 'C:/Windows/Fonts/msyh.ttc', size = 30)
def creating_watermark(im, text, font = font):
#给水印添加透明度,因此需要转换图片的格式
im_rgba = im.convert('RGBA')
im_text_canvas = Image.new('RGBA', im_rgba.size, (255, 255, 255, 0))
print(im_rgba.size[0])
#创建画布对象
draw = ImageDraw.Draw(im_text_canvas)
#设置文本文字大小
text_x_width, text_y_height = draw.textsize(text, font = font)
print(text_x_width, text_y_height)
text_xy = (im_rgba.size[0] - text_x_width, im_rgba.size[1] - text_y_height)
print(text_xy)
#设置文本颜色(绿色)和透明度(半透明)
draw.text(text_xy, text, fill = (255, 255, 255, 128), font = font)
#将原图片与文字复合
im_text = Image.alpha_composite(im_rgba, im_text_canvas)
return im_text
image = Image.open("C:/Users/Administrator/Desktop/c-net.png")
im.show()
image_water = creating_watermark(image, '@c语言中文网')
image_water.show()
image_water.save("C:/Users/Administrator/Desktop/c语言中文网.png")
添加水印后的效果图

十一、Pillow和ndarray数组
NumPy 是 Python 科学计算的基础数据包,它被大量的应用于机器学习领域,比如图像识别、自然语言处理、数据挖掘等。想了解学习 NumPy,可跳转至《NumPy快速入门教程》。
ndarray 是 NumPy 中的数组类型,也称为 ndarray 数组,该数组可以与 Pillow 的 PIL.Image 对象实现相互转化。
1. ndarray数组创建图像
下面通过一个ndarray数组构建一个Image对象,并将图像显示出来。示例如下:
#导入相关的包
from PIL import Image
#使用numpy之前需要提前安装
import numpy as np
#创建 300*400 的图像,3个颜色通道
array = np.zeros([300, 400, 3], dtype = np.unit8)
#rgb色彩模式
array[:, :200] = [255, 0 , 0]
array[:, 200:] = [255, 255 , 0]
img = Image.fromarray(array)
img.show()
img.save("C:/Users/Administrator/Desktop/数组生成图像.png")
输出结果如下所示:

2. 图像转换为ndarray数组
下面将图像以ndarray数组的形式进行输出,示例如下:
from PIL import Image
import numpy as np
img = Image.open("C:/Users/Administrator/Desktop/大熊猫.png")
img.show()
#Image图像转换为ndarray数组
img_2 = np.array(img)
print(img_2)
#ndarray数组转换为Image图像
arr_img = Image.fromarray(img_2)
#显示图片
arr_img.show()
#保存图片
arr_img.save("C:/Users/Administrator/Desktop/arr_img.png")
图片显示结果:

组成图片的像素点数组如下所示:
[[[113 108 105]
[118 113 110]
[139 131 128]
...
[139 148 155]
[137 146 153]
[139 148 155]]
[[ 97 92 89]
[124 118 115]
[137 129 126]
...
[143 152 159]
[140 149 156]
[140 149 156]]
[[102 97 94]
[123 118 115]
[135 128 125]
...
[144 153 160]
[142 151 158]
[143 152 159]]
...
[[168 175 134]
[175 183 142]
[151 162 120]
...
[ 99 143 66]
[111 155 77]
[131 175 98]]
[[152 164 118]
[147 160 114]
[140 156 109]
...
[123 167 87]
[126 171 90]
[120 165 84]]
[[136 154 104]
[127 145 95]
[156 176 125]
...
[168 213 130]
[142 187 104]
[ 69 114 31]]]
想要了解关于 Pillow 的更多的知识,请参考官方文档:点击前往
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)