探索Pillow库:Python图像处理的艺术之旅
Pillow是一个开源的Python Imaging Library(PIL)的派生项目,它旨在提供一个更加用户友好、功能丰富且易于安装使用的图像处理库。Pillow不仅兼容PIL的大多数功能,还增加了一些新特性,支持了更新的图像文件格式,并且在持续维护中,确保与最新版本的Python兼容。
主要特点:
广泛格式支持:Pillow能够处理各种图像文件格式,包括但不限于PNG、JPEG、GIF、BMP、TIFF、WebP等,无论是读取、操作还是保存这些格式的图片。
基本图像处理:提供了基础的图像操作功能,如裁剪、旋转、调整大小、翻转、滤镜应用(如模糊、锐化)、颜色模式转换等。
高级功能:包括图像增强、直方图操作、序列图像处理(动画GIF)、文字渲染到图像上以及简单的绘图功能。
图像分析:可以提取图像的元数据信息,进行基本的图像统计分析,比如计算图像的像素值分布等。
兼容性和扩展性:Pillow设计为易于与其他Python库集成,如NumPy、OpenCV等,使得在科学计算、机器学习和计算机视觉项目中处理图像变得更加灵活和强大。
跨平台:Pillow可以在多种操作系统上运行,包括Windows、macOS和各种Linux发行版,保证了代码的可移植性。
安装
使用如下命令安装最新版的pillow
pip install --upgrade pillow
导入
pillow的Image对象是最主要的操作图像的类,使用如下代码导入:
from PIL import Image
创建Image
使用Image类的new()
方法可以创建一个新的Image对象,语法格式如下:
img = Image.new(mode, size, color)
参数说明如下:
mode
:图像模式,字符串参数,比如RGB(真彩图像)、L(灰度图像)、CMYK(色彩图打印模式)等size
:图像大小,元组参数(width, height)代表图像的像素大小color
:可选参数,指定图像的背景色。如果未提供,默认值通常是黑色或透明,具体取决于模式。参数值支持(R,G,B)三元组数字格式、颜色的十六进制值以及颜色英文单词(如black等)
例如,创建一个 300x200 像素的 RGB 模式的红色空白图像:
from PIL import Image, ImageColor
# 创建一个红色的图像
red_image = Image.new('RGB', (300, 200), ImageColor.getcolor('red', 'RGB'))
red_image.save('red_image.png') # 保存图像
创建一个 200x200 像素的灰度模式的空白图像:
gray_image = Image.new('L', (200, 200))
gray_image.save('gray_image.png')
读取和显示图像
from PIL import Image
# 打开图像
img = Image.open('test.png')
# 显示图像
img.show(title="hello_pillow")
运行后自动打开电脑默认图片浏览器浏览对应图片
Image对象属性
Image对象有一些常用的基本属性,这些属性能够帮助我们了解图片的基本信息,以下是一些常用的属性:
mode:返回图像的颜色模式。例如,'L' 表示灰度图像,'RGB' 表示真彩色图像,'RGBA' 表示带有透明通道的彩色图像等。
size:返回一个包含图像宽度和高度的二元组,如
(width, height)
。format:如果图像文件已经加载或者已经保存过,则返回图像的格式(如 'JPEG'、'PNG' 等)。如果图像没有关联的文件格式,此属性可能返回 None。
width:返回图像的宽度(以像素为单位)。
height:返回图像的高度(以像素为单位)。
palette:对于使用调色板的图像(如 GIF 或者某些模式的 PNG),此属性返回一个包含调色板颜色的元组列表。对于非调色板模式的图像,返回 None。
info:返回一个字典,包含图像的元数据信息。这可能包括分辨率、作者、版权等信息,具体取决于图像的来源和格式。
from PIL import Image
# 打开一个图像文件
image = Image.open("example.jpg")
# 访问并打印图像的属性
print(f"Image Mode: {image.mode}")
print(f"Image Size: {image.size}")
print(f"Image Format: {image.format}")
print(f"Width: {image.width}")
print(f"Height: {image.height}")
# 如果适用,检查图像的调色板和元数据信息
if image.palette:
print("Image has a palette.")
else:
print("Image does not have a palette.")
print("Image Metadata:")
print(image.info)
图像的保存与转换
为了保存图像,我们可以使用Image.save()
方法,这个方法支持多种图像格式,并且可以自定义保存时的一些选项,如压缩质量、是否保留元数据等。
Image.save(fp, format=None)
fp
: 字符串或者文件对象。如果是字符串,它应该是保存图像的文件路径,包括文件名和扩展名。如果是文件对象,Pillow 将会写入该文件对象。format
: 可选参数,指定保存图像的格式。如果你省略了这个参数,Pillow 通常会根据文件名的扩展名来推断格式。如果你通过文件对象保存图像,这个参数就是必需的。**options
: 这些是格式特定的选项,比如 JPEG 的质量、PNG 的压缩级别等。具体的选项依据不同的图像格式而定。
from PIL import Image
img = Image.open('test.jpg')
img.save('output.jpg', quality=90)
同时,Image.save()
方法也支持图像格式的转换,这里列出了一些主要格式及其相互之间的转换能力:
从JPEG转换到:
PNG
GIF
BMP
TIFF
WebP
PPM/PGM/PBM(取决于图像色彩模式)
ICO(某些情况下,可能受限于图标特定要求)
从PNG转换到:
JPEG
GIF(注意透明度会丢失)
BMP
TIFF
WebP
PPM/PGM/PBM
ICO(可能需要特别处理透明度)
从GIF转换到:
JPEG
PNG(可保留动画为多个帧或单帧)
BMP
TIFF
WebP(可能不支持动画)
PPM/PGM/PBM(单帧)
从BMP转换到:
JPEG
PNG
GIF
TIFF
WebP
PPM/PGM/PBM
从TIFF转换到:
JPEG
PNG
GIF
BMP
WebP
PPM/PGM/PBM
注意:TIFF支持多种压缩和数据类型,转换时可能需要特别考虑设置。
从WebP转换到:
JPEG
PNG
GIF(可能丢失动画)
BMP
TIFF
PPM/PGM/PBM
矢量格式特别说明:
SVG到其他格式:虽然Pillow直接操作SVG的能力有限,但可以借助其他库先转换为像素图像再用Pillow处理。
PDF转换:Pillow支持读取和保存为PDF,但转换细节和限制较多,可能需要额外配置。
转换时,通过指定不同的扩展名或使用format
参数来指示目标格式(当然也可以不显式指定格式)。例如,将PNG转换为JPEG:
from PIL import Image
img = Image.open('test.png')
img.save('test.jpg')
img.save('test.jpg', format='JPEG')
图像缩放
在图像处理过程中经常会遇到缩小或放大图像的情况,Image.resize()
方法能够让用户改变图像的宽度和高度,同时可以选择不同的插值方法来控制缩放后的图像质量。
基本语法如下:
resized_image = image.resize(size, resample=RESAMPLE)
下面是参数说明:
size:一个包含两个整数的元组
(width, height)
,分别代表目标图像的宽度和高度。你可以直接提供具体的像素值,或者使用一个比例因子(例如,(200, 200)
表示将图像调整为200x200像素)。resample:这是一个可选参数,用于指定在调整尺寸时所使用的插值算法。默认值通常为
Image.BILINEAR
,适用于大多数情况。可用的插值方法包括但不限于:Image.NEAREST
:最近邻插值,速度快但质量较低,适合像素艺术或需要硬边界的图像。Image.BILINEAR
:双线性插值,速度适中,质量较好,适合大多数放大或缩小操作。Image.BICUBIC
:三次样条插值,质量更高但较慢,适合高质量的缩放。Image.LANCZOS
:高质量的 lanczos 插值,效果很好但计算最慢,适合高质量打印或缩放。
示例:
from PIL import Image
# 打开图像
image = Image.open('test.png')
# 获取图像的原始宽度和高度
width, height = image.size
# 计算等比例缩放的高度,保持宽高比不变
ratio = 400 / width
new_height = int(height * ratio)
# 使用双线性插值进行尺寸调整
resized_image = image.resize((400, new_height), resample=Image.BILINEAR)
# 保存调整尺寸后的图像
resized_image.save('resized_test.jpg')
创建缩略图
缩略图(thumbnail image)指的是将原图缩小至一个指定大小(size)的图像。通过创建缩略图可以使图像更易于展示和浏览。
image.thumbnail()
用来生图像的缩略图。与 resize()
方法不同,thumbnail()
更适用于快速生成预览图或缩略图,因为它自动处理比例调整,确保图像不失真。
基本语法如下:
image.thumbnail(size,resample)
下面是参数说明:
size:一个包含两个整数的元组
(width, height)
,分别代表目标图像的宽度和高度。你可以直接提供具体的像素值,或者使用一个比例因子(例如,(200, 200)
表示将图像调整为200x200像素)。resample:这是一个可选参数,用于指定在调整尺寸时所使用的插值算法。默认值通常为
Image.BILINEAR
,适用于大多数情况。可用的插值方法包括但不限于:Image.NEAREST
:最近邻插值,速度快但质量较低,适合像素艺术或需要硬边界的图像。Image.BILINEAR
:双线性插值,速度适中,质量较好,适合大多数放大或缩小操作。Image.BICUBIC
:三次样条插值,质量更高但较慢,适合高质量的缩放。Image.LANCZOS
:高质量的 lanczos 插值,效果很好但计算最慢,适合高质量打印或缩放。
示例:
from PIL import Image
# 打开图像
image = Image.open('test.png')
# 使用thumbnail方法创建一个最大边长为200像素的缩略图, 并保持原图的宽高比
image.thumbnail((200, 200))
# 保存并展示缩略图
image.save('test_thumbnail.jpg') # 保存
image.show() # 显示
PIL与numpy
Pillow和NumPy的ndarray数组在处理图像数据时经常一起使用。
Pillow主要用于图像文件的读取、显示、保存等操作,而NumPy的ndarray则提供了强大的数组处理功能,特别适合进行数值运算和图像处理中的像素级操作。
下面介绍它们是如何相互转换的
Image转换为ndarray
当你从一个图像文件加载图像后,可以将其转换为NumPy数组以便进行数学运算或使用科学计算库。
from PIL import Image
import numpy as np
# 使用Pillow打开图像
image = Image.open("example.jpg")
# 将Pillow图像转换为NumPy数组
numpy_array = np.array(image)
print(numpy_array.shape) # 输出数组形状,通常是(height, width, channels)
两个维度代表图像的宽度和高度,第三个维度代表颜色通道(例如RGB图像有3个通道)。
ndarray转换为Image
完成一些数组操作后,你可能需要将修改后的数组再次转换为Pillow图像以显示或保存
from PIL import Image
import numpy as np
# 假设我们对numpy_array进行了某些操作
modified_array = np.where(numpy_array > 128, 255, 0) # 仅作为示例,将亮度大于128的像素置为白色,其余置为黑色
# 将修改后的NumPy数组转换回Pillow图像
modified_image = Image.fromarray(modified_array.astype('uint8'))
# 保存并展示修改后的图像
modified_image.save("modified_example.jpg")
modified_image.show()