Pillow 是 Python3 最常用的图像处理库,官方给出的主要用途:图像的档案(图片的批处理、缩略图绘制)、图像显示(在Tkinter框架下使用)、图像处理(支持点运算、卷积核滤波、色彩空间转化、大小变换、旋转、仿射变换)
Pillow支持的图片格式很广泛(extensive file format support)
使用 pip 安装 Pillow:pip install Pillow
2.1 创建实例对象
Image类——最常用的类,创建图像实例——最重要的类
from Pil import Image
image = Image.open('python-logo.png') # 创建图像实例,路径地址,可自动判定图片格式,失败引起
#im = Image.open(io.StringIO(buffer)) #要从字符串数据中读取图像,需使用 io 类
IOError异常
# 查看图像实例的属性
print(image.format, image.size, image.mode)
'''
PPM (512, 512) RGB
实例属性说明:
format 图像格式
size 图像的 (宽,高) 元组
mode 常见模式,默认 RGB 真彩图像;L (亮度)为灰阶图像;CMYK 印刷色彩;RGBA 带透明度的真彩图像;YCbCr 彩色视频格式;LAB L * a * b颜色空间;HSV 等。
'''
image.show() # 显示图像
还有其他方法:从打开文件中读取(with open(...,...)as ...、从二进制流中读取、从tar文件中读取;
2.2 读写图像
2.2.1文件格式转换(后缀名)
import os
from PIL import Image
image_path='python-logo.png' # 图片位置
f, e = os.path.splitext(image_path) # 获取文件名与后缀
outfile = f + ".jpg"
if image_path != outfile:
try:
Image.open(image_path).save(outfile) # 修改文件格式
except IOError:
print("cannot convert", image_path)
Image.open(image_path).convert("RGB").save(outfile) # convert 转换为 RGB 格式,丢弃Alpha
图片mode:RGBA 红色,绿色,蓝色,Alpha 的色彩空间,Alpha 是指透明度
2.2.2 创建缩略图
try:
im = Image.open(image_path)
im.thumbnail(size) # 设置缩略图大小
im.save(outfile_name, "JPEG")
except IOError:
print("cannot convert", image_path)
2.3剪贴、粘贴、合并
2.3.1从图像复制子矩形
box = (100, 100, 400, 400)#基于左上角(0,0)(上下左右)的坐标
region = im.crop(box)
2.3.2粘贴到目标位置
region = region.transpose(Image.ROTATE_180) # 颠倒180度
box = (400, 400, 700, 700) # 粘贴位置,像素必须吻合,300 * 300
im.paste(region, box)
高级玩法:图像滚动的实现
def roll(image, delta):
""" 向侧面滚动图像 """
xsize, ysize = image.size
delta = delta % xsize
if delta == 0: return image
part1 = image.crop((0, 0, delta, ysize))
part2 = image.crop((delta, 0, xsize, ysize))
image.paste(part1, (xsize - delta, 0, xsize, ysize))
image.paste(part2, (0, 0, xsize - delta, ysize))
return image
if __name__ == '__main__':
image_path = 'test.jpg'
im = Image.open(image_path)
roll(im, 300).show() # 向侧面滚动 300 像素
*高级玩法:加有一定透明度的蒙版
蒙版的值为255表示不透明,值为0表示完全透明。黏贴RGBA图像时,注意不透明部分与透明背景的设置。
2.3.3 通道操作(合并与分离)
单通道图像返回图像本身
多通道(如RGB三通道),split可将通道费分离,merge()用于合成。
处理单色系时,可先将图片转为RGB
r, g, b = im.split()#单通道则返回图片本身,处理多通道图像,应先转换为RGB
im = Image.merge("RGB", (b, g, r))
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 im
*高级玩法:两张图片组合扩大
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 im
paset
2.3.4几何变换
out = im.resize((128, 128))#调整后的大小(像素)
out = out.rotate(45)#逆时针旋转45度
要以90度为单位旋转图像,可以使用 rotate() 或 transpose() 方法。后者也可用于围绕其水平轴或垂直轴翻转图像。
示例:
out = im.transpose(Image.FLIP_LEFT_RIGHT) # 水平左右翻转
out = im.transpose(Image.FLIP_TOP_BOTTOM) # 垂直上下翻转
out = im.transpose(Image.ROTATE_90) # 逆时针90度
out = im.transpose(Image.ROTATE_180) # 逆时针180度
out = im.transpose(Image.ROTATE_270) # 逆时针270度
rotate() 和 transpose() 方法相同,他们之间没有差别, transpose() 方法比较通用。
2.3.5 颜色变换
im = Image.open("hopper.ppm").convert("L") # 转换为灰阶图像
注意:它支持每种模式转换为"L" 或 "RGB",要在其他模式之间进行转换,必须先转换模式(通常为“RGB”图像,即RGB图像可作为中间过渡的图象)
2.4图片增强
2.4.1 ImageFilter模块包括二类预先定义好的过滤器,使用filter()方法可以调用
from PIL import ImageFilter
out = im.filter(ImageFilter.DETAIL)
'''
BLUR
CONTOUR
DETAIL
EDGE_ENHANCE
EDGE_ENHANCE_MORE
EMBOSS
FIND_EDGES
SHARPEN
SMOOTH
SMOOTH_MORE
'''
2.4.2点运算
point()方法
# multiply each pixel by 1.2
out = im.point(lambda i: i * 1.2)
# split the image into individual bands
source = im.split()
R, G, B = 0, 1, 2
# select regions where red is less than 100
mask = source[R].point(lambda i: i < 100 and 255)
# process the green band
out = source[G].point(lambda i: i * 0.7)
# paste the processed band back, but only where red was < 100
source[G].paste(out, None, mask)
# build a new multiband image
im = Image.merge(im.mode, source)
2.4.3增强
ImageEnhangce.Contrast()\Color\Britghtness\Sharpness调整对比度、亮度、色彩、对比度
from PIL import ImageEnhance
enh = ImageEnhance.Contrast(im)
enh.enhance(1.3).show("30% more contrast")
2.4.4图像序列(动画格式Animation formats)
支持格式FLI、FLC、GIF,这些图像包括了多个帧,可用seek()、tell()移动
from PIL import Image
with Image.open("animation.gif") as im:
im.seek(1) # 跳到第二帧
try:
while 1:
im.seek(im.tell() + 1)
# do something to im
except EOFError:
pass # end of sequence
from PIL import ImageSequence
for frame in ImageSequence.Iterator(im):
# ...do something to frame...
其他说明
支持读取二级制文件、URL(加载使用urllib.request包)、tar压缩文件
其他功能可以看官方文档https://pillow.readthedocs.io/en/latest/reference/Image.html#PIL.Image.Image.draft