PIL库全称为Python Imaging Library,即Python图像处理库,是一个在Python中用于处理图像的非常流行的库。
一、PIL介绍
这个库提供了广泛的文件格式支持、高效的内部表示以及相当强大的图像处理功能。
核心图像库旨在快速访问存储在几种基本像素格式中的数据。为通用图像处理工具提供坚实的基础。
官网地址: https://pillow.readthedocs.io/en/stable/installation/index.html
主要功能:
- 图像归档
Python图像库非常适合图像归档和批量处理应用。您可以使用该库创建缩略图、在文件格式之间进行转换、打印图像等。当前版本能够识别和读取大量的格式。写入支持有意限制在最常用的交换和展示格式。 - 图像显示
当前版本包括Tk PhotoImage和BitmapImage接口,以及可以与PythonWin和其他基于Windows的工具包一起使用的Windows\DIB接口。许多其他GUI工具包也附带了某种PIL支持。对于调试,还有一个show()方法,该方法将图像保存到磁盘,并调用外部显示实用程序。 - 图像处理
库包含基本的图像处理功能,包括点操作、使用一系列内置卷积核进行过滤以及颜色空间转换。该库还支持图像缩放、旋转和任意仿射变换。
二、Image类介绍
PIL库中最重要的类就是Image类,它定义在同名模块中。可以通过几种方式创建此类的实例;要么从文件加载图像,处理其他图像,或者从头开始创建图像。从文件加载图像时,使用 Image 模块中的 open() 函数
源码:
def open(fp, mode="r", formats=None):"""Opens and identifies the given image file.This is a lazy operation; this function identifies the file, butthe file remains open and the actual image data is not read fromthe file until you try to process the data (or call the:py:meth:`~PIL.Image.Image.load` method). See:py:func:`~PIL.Image.new`. See :ref:`file-handling`.:param fp: A filename (string), pathlib.Path object or a file object.The file object must implement ``file.read``,``file.seek``, and ``file.tell`` methods,and be opened in binary mode.:param mode: The mode. If given, this argument must be "r".:param formats: A list or tuple of formats to attempt to load the file in.This can be used to restrict the set of formats checked.Pass ``None`` to try all supported formats. You can print the set ofavailable formats by running ``python3 -m PIL`` or usingthe :py:func:`PIL.features.pilinfo` function.:returns: An :py:class:`~PIL.Image.Image` object.:exception FileNotFoundError: If the file cannot be found.:exception PIL.UnidentifiedImageError: If the image cannot be opened andidentified.:exception ValueError: If the ``mode`` is not "r", or if a ``StringIO``instance is used for ``fp``.:exception TypeError: If ``formats`` is not ``None``, a list or a tuple."""
参数说明:
-
fp: 文件名(字符串)、pathlib.Path对象或文件对象。file.read、file.seek和file.tell方法,并且必须以二进制模式打开。
-
mode: 模式。如果给出,此参数必须为"r"。
-
formats: 尝试加载文件的一系列格式列表或元组。这可用于限制检查的格式集合。传递None以尝试所有受支持的格式。
from PIL import Imageim = Image.open("./images/img.png")print(im.format, im.size, im.mode)
# 此函数将返回一个Image对象。可以使用实例属性来检查文件内容:
# PNG (640, 464) RGBA
- format属性标识图像的来源。如果图像不是从文件中读取的,则设置为 None。
- size属性是一个包含宽度和高度(以像素为单位)的 2-元组。
- mode属性定义了图像中的波段数量和名称,以及像素类型和深度。常见的模式有“L”(亮度)用于灰度图像,“RGB”用于真彩色图像,以及“CMYK”用于预印刷图像。
- R: Red(红色)
- G: Green(绿色)
- B: Blue(蓝色)
- A: Alpha(透明度)
如果文件无法打开,则会触发OSError异常。
一旦拥有Image类的实例,就可以使用此类定义的方法来处理和操作图像。例如,加载图像:
注意:标准版本的show()效率不是很高,因为它会将图像保存到临时文件并调用实用程序来显示图像。
im.show())
三、读取和写入图像
Python Imaging Library 支持多种图像文件格式。要从磁盘读取文件,使用Image 模块中的open()函数。无需知道文件格式即可打开文件。库将根据文件内容自动确定格式。
要保存文件,使用Image类的save()方法。在保存文件时,名称变得重要。除非指定格式,否则库将使用文件扩展名来确定要使用哪种文件存储格式。
1. 将文件转换为 JPEG
from PIL import Imageim = Image.open("./images/word_image1.png")
# 文件转为jpge
im.save('./images/img.jpg')
save() 方法可以提供第二个参数,明确指定文件格式。
2. 创建 JPEG 缩略图
from PIL import Imageim = Image.open("./images/word_image1.png")
im.thumbnail((128,128))
im.save('./images/img.thumbnail', "JPEG")
注意: 除非需要,否则库不会对光栅数据进行解码或加载。当打开文件时,会读取文件头以确定文件格式并提取诸如模式、大小以及其他所需的属性,但直到稍后才处理其余的文件。
这意味着打开图像文件是一个快速操作,与文件大小和压缩类型无关。
3. 识别图像文件
from PIL import Imageim = Image.open("./images/word_image1.png")# 识别图像
with im as img:print('./images/word_image1.png', img.format, f"{img.size}x{img.mode}")
# ./images/word_image1.png PNG (2218, 582)xRGB
四、裁剪、粘贴和合并图像
Image 类包含允许操作图像内区域的方法。要从图像中提取子矩形,使用copy()方法。
1. 从图像中复制一个子矩形
box = (100, 100, 400, 400)
region = im.crop(box)
该区域由一个元组定义,其中坐标为 (左,上,右,下)。Python Imaging Library 使用的坐标系统以 (0, 0) 在左上角。坐标指的是像素之间的位置,因此上述示例中的区域正好是 300x300 像素。
该区域可以以某种方式进行处理并粘贴回去。
2. 处理子矩形
region = region.transpose(Image.Transpose.ROTATE_180)
im.paste(region, box)
粘贴区域回去时,区域的大小必须与给定区域完全匹配。此外,区域不能超出图像范围。然而,原始图像和区域的模式无需匹配。如果它们不匹配,区域将在粘贴前自动转换。
3. 滚动图像
def roll(im, delta):"横向滚动图像。"xsize, ysize = im.sizedelta = delta % xsizeif delta == 0:return impart1 = im.crop((0, 0, delta, ysize))part2 = im.crop((delta, 0, xsize, ysize))im.paste(part1, (xsize - delta, 0, xsize, ysize))im.paste(part2, (0, 0, xsize - delta, ysize))return imim.show()
im1 = roll(im, 200)
im1.show()
4. 合并图像
def merge(im1, im2):w = im1.size[0] + im2.size[0]h = max(im1.size[1], im2.size[1])im = Image.new("RGBA", (w, h))im.paste(im1)im.paste(im2, (im1.size[0], 0))return imim = Image.open("./images/img.png")
im2 = Image.open('./images/img_1.png')merge_img = merge(im, im2)
merge_img.show()
对于更高级的技巧,paste()方法还可以接受一个透明度蒙版作为可选参数。在这个蒙版中,值 255 表示粘贴的图像在该位置是不透明的(即,应使用粘贴的图像)。值 0 表示粘贴的图像完全透明。中间值表示不同程度的透明度。例如,粘贴一个 RGBA 图像并同时使用它作为蒙版会粘贴图像的不透明部分,但不包括其透明背景。
Python Imaging Library 还允许使用多波段图像的各个波段,例如 RGB 图像。split()方法创建一组新图像,每个图像包含原始多波段图像的一个波段。merge 函数采用一个模式和图像元组,并将它们合并成一张新图像。以下示例交换了一个 RGB 图像的三个波段:
5. 分割和合并波段
r, g, b, a = im.split()im = Image.merge("RGBA", (b, g, r, a))
im.show()
对于单波段图像,split() 返回图像本身。要使用单独的颜色波段,需要先将图像转换为“RGB”。
五、几何变换
PIL.Image.Image 类包含 resize() 和 rotate() 图像的方法。前者接受一个元组,给出新的大小,后者是逆时针角度。
1. 简单的几何变换
out = im.resize((128, 128))
out = im.rotate(45) # 逆时针度数
2. 转置图像
要以 90 度的步长旋转图像,可以使用rotate()方法或transpose() 方法。后者也可以用来围绕图像的水平或垂直轴翻转图像。
out = im.transpose(Image.Transpose.FLIP_LEFT_RIGHT)
out = im.transpose(Image.Transpose.FLIP_TOP_BOTTOM)
out = im.transpose(Image.Transpose.ROTATE_90)
out = im.transpose(Image.Transpose.ROTATE_180)
out = im.transpose(Image.Transpose.ROTATE_270)
其中值的含义:
- FLIP_LEFT_RIGHT:水平翻转图像,意味着图像的内容会在水平方向上镜像,就像照镜子一样,左边的内容会出现在右边,右边的出现在左边。
- FLIP_TOP_BOTTOM:垂直翻转图像,图像的内容会在垂直方向上镜像,顶部的内容会移到底部,底部的移到顶部。
- ROTATE_90:顺时针旋转图像90度。
- ROTATE_180:顺时针旋转图像180度。
- ROTATE_270:顺时针旋转图像270度,或等价地说逆时针旋转90度。
- TRANSPOSE:交换图像的宽度和高度,相当于顺时针旋转90度后再水平翻转,或逆时针旋转270度。
- TRANSVERSE:交换图像的宽度和高度后,再垂直翻转,相当于顺时针旋转270度后再水平翻转,或逆时针旋转90度。
transpose(ROTATE) 操作也可以通过rotate() 操作以相同的方式执行,前提是 expand标志为 true,以提供对图像大小的相同更改。
可以通过transform() 方法执行更通用的图像转换。
3. 调整大小
除了在调整大小时计算新图像的大小外,还可以选择相对于给定大小进行调整大小。
size = (100, 150)
with im as im:ImageOps.contain(im, size).save("./images/imageops_contain.png")ImageOps.fit(im, size).save("./images/imageops_fit.png")ImageOps.pad(im, size, color="#f00").save("./images/imageops_pad.png")
ImageOps的方法:
- ImageOps.contain(im, size):
- 含义:这个方法会按比例缩放图像,使其完全适合给定的size(宽度和高度),同时保持原始图像的宽高比。与size相比,图像可能不会填满整个指定区域,但图像内容将完整无裁剪地显示在新的尺寸内。
- ImageOps.fit(im, size):
- 含义:此方法会缩放图像,使其适应给定的size,同时保持原始的宽高比。与contain不同,fit允许指定一个具体的缩放方法(默认是双线性插值),并且可以选择是否在必要时裁剪图像,以确保输出图像的尺寸严格等于指定的尺寸。
- ImageOps.pad(im, size, color=“#f00”):
- 含义:这个方法会在图像周围添加一个颜色填充的边框,使最终的图像尺寸符合size要求。如果原图尺寸大于指定尺寸,则会对图像进行居中裁剪至指定大小,然后在四周加上指定颜色的边框。color参数定义了边框的颜色,这里的"#f00"代表纯红色。