Python Pillow(PIL)库的用法介绍(二)

Python Pillow(PIL)库的用法介绍(二)

在上一篇文章中介绍了Pillow库的一些基本用法,参考:https://blog.csdn.net/weixin_43790276/article/details/108478270

Pillow库的功能非常多,本文继续介绍。

官方文档路径:https://pillow.readthedocs.io/en/latest/

一、图片的变换

原图:

# coding=utf-8
from PIL import Image


image = Image.open("yazi.jpg")
data = (200, 300, 1100, 1200)
image_trans = image.transform((500, 400), Image.EXTENT, data=data, resample=Image.NEAREST, fillcolor='blue')
image_trans.show()

运行结果:

transform(size, method, data=None, resample=NEAREST, fill=1, fillcolor=None): 对图片进行变换,截取的同时进行缩放和填充等。返回指定大小的图片副本,图片的模式与原图相同。有6个参数。

size, 返回图片的尺寸。传入一个长度为2的元组(width, height)。

method, 转换方法。可以传入Image.EXTENT(一个矩形区), Image.AFFINE(仿射变换), Image.PERSPECTIVE(透视变换), Image.QUAD(一个四边形映射到一个矩形), Image.MESH(图源的四边形在一个操作)。

data, 转换方法需要的额外数据。需要根据method的不同传入不同的数据,这个参数是辅助method的,强依赖于转换方法method,格式不匹配会报错(格式详见源码中的__transformer()方法)。

(1) method为Image.EXTENT时,data格式为(x0, y0, x1, y1),传入截取矩形区域的坐标,可以超出原图的边界。

(2) method为Image.AFFINE时,data格式为(a, b, c, d, e, f),将原图中(ax+by+c, dx+ey+f)坐标的点映射到返回图片的(x, y)坐标。

(3) method为Image.PERSPECTIVE时,data格式为(a, b, c, d, e, f, g, h),将原图中((ax+by+c)/(gx+hy+1),  (dx+ey+f)/(gx+hy+1))坐标的点映射到返回图片的(x, y)坐标,如果后面两个数g, h为0,则效果与Image.AFFINE相同,其实g, h一般都用0,因为随着x和y变大,相当于要除一个很大的数,原图基本会被缩成一个点。

(4) method为Image.QUAD时,data格式为(x0, y0, x1, y1, x2, y2, x3, y3),传入一个四边形的四个坐标(西北,西南,东南,东北),将这个四边形映射到返回的矩形图片中。

(5) method为Image.MESH时,其实MESH转换方法的源码(for box, quad in data:)中有错误,需要自己修改后才能用。

resample, 重采样,是一个可选的重采样过滤器。可以传入Image.NEAREST, Image.BILINEAR, Image.BICUBIC。默认为Image.NEAREST。如果图像的模式为'1'或'P',则始终设置为Image.NEAREST。

fill, 填充。如果method参数是一个Image.ImageTransformHandler对象,fill是传给转换方法的一个参数,否则,fill无效。

fillcolor, 填充颜色。超出原图区域的部分使用此颜色填充。

现在将不同转换方法method的效果进行对比。

from PIL import Image


image = Image.open("yazi.jpg")
# data = (200, 300, 1100, 1200)
# image_trans = image.transform((500, 400), Image.NEAREST, data=data, resample=Image.NEAREST, fillcolor='blue')
# image_trans.show()
# data = (0, 1, 300, 1, 0, 400)
# image_trans = image.transform((500, 400), Image.AFFINE, data=data, resample=Image.NEAREST, fillcolor='blue')
# image_trans.show()
# data = (0, 1, 500, 1, 0, 400, 0, 0)
# image_trans = image.transform((500, 400), Image.PERSPECTIVE, data=data, resample=Image.NEAREST, fillcolor='blue')
# image_trans.show()
data = (300, 200, 300, 500, 800, 800, 1100, 0)
image_trans = image.transform((500, 400), Image.QUAD, data=data, resample=Image.NEAREST, fillcolor='blue')
image_trans.show()

运行结果:

二、图片的分离

from PIL import Image


image = Image.open("yazi.jpg")
print(image.mode)
r, g, b, a = image.split()
print(r.mode, r.size)
print(g.mode, g.size)
print(b.mode, b.size)
print(a.mode, a.size)
# r.show()
# g.show()
# b.show()
a.show()

运行结果:

RGBA
L (1557, 911)
L (1557, 911)
L (1557, 911)
L (1557, 911)

split(): 对图片进行分离提取。将此图片分离成单独的颜色通道。返回组成原图的单颜色通道图片元组。如分离'RGB'图片会返回三张新图片,每张图片是一个颜色通道(红色,绿色,蓝色)的副本,都是灰度的图片。同理,'RGBA'返回四张新图片。

如果只需要提取其中一种颜色的图片,可以使用getchannel(channel)方法。

r = image.getchannel('R')
print(r.mode, r.size)
r.show()

运行结果:

L (1557, 911)

getchannel(channel): 分离出原图中的一个颜色通道。如分离'RGB'图片中的某个通道时可以传入'R', 'G', 'B'或0, 1, 2来进行分离。分离'RGBA'中的'A'时只能传入'A',不能传入3。

三、图片的合并

from PIL import Image


image = Image.open("yazi.jpg")
r, g, b, a = image.split()
image_merge = Image.merge('RGB', (r, g, a))
print(image_merge.mode, image_merge.size)
image_merge.show()

运行结果:

RGB (1557, 911)

merge(mode, bands): 将多个单通道的图片合并成一张多通道的图片。merge()是Image模块中的一个函数,不是Image类中的方法,有两个参数。

mode, 需要合成的目标图片的模式。如'RGB','RGBA'。

bands, 用于合并的单通道图片列表。传入一个列表或元组,列表长度与目标图片的模式要对应,如'RGB'需要传入长度为3的列表,'RGBA'需要传入长度为4的列表。列表中的每张单通道图片尺寸必须相同,否则报错。

四、图片的过滤

1. 图片过滤器

Pillow提供了以下预定义的图片过滤器,参考:https://pillow.readthedocs.io/en/latest/reference/ImageFilter.html#module-PIL.ImageFilter

filter描述
BLUR模糊
CONTOUR轮廓
DETAIL详情
EDGE_ENHANCE边缘增强
EDGE_ENHANCE_MORE边缘增强更多
EMBOSS电磁波
FIND_EDGES寻找边缘
SHARPEN夏普
SMOOTH光滑
SMOOTH_MORE更光滑

2. 图片的过滤

from PIL import Image, ImageFilter


image = Image.open("yazi.jpg")
# image_blur = image.filter(ImageFilter.BLUR)
# image_blur.show()
# image_contour = image.filter(ImageFilter.CONTOUR)
# image_contour.show()
# image_edge = image.filter(ImageFilter.EDGE_ENHANCE_MORE)
# image_edge.show()
image_emboss = image.filter(ImageFilter.EMBOSS)
image_emboss.show()

运行结果:

filter(filter): 使用指定的过滤器对图片进行过滤。传入一个ImageFilter过滤器,上面表格中的过滤器都支持。

五、图片的混合

为了体现出混合的效果,需要使用两张图片,所以再加入一张图片。

from PIL import Image


image = Image.open('yazi.jpg').crop((100, 100, 1300, 900))
image2 = Image.open('yazi2.jpg').crop((100, 0, 1300, 800))
image.save('duck1.png')
image2.save('duck2.png')
duck1 = Image.open('duck1.png')
duck2 = Image.open('duck2.png')
print(duck1.size, duck1.mode)
print(duck2.size, duck2.mode)
image_blend = Image.blend(duck1, duck2, 0.7)
image_blend.show()

运行结果:

(1200, 800) RGBA
(1200, 800) RGBA

blend(im1, im2, alpha): 将两张图片混合成一张图片。blend()是Image模块中的一个函数,不是Image类中的方法,有3个参数。

im1, 混合的第一张图片。

im2, 混合的第二张图片。图片的尺寸和模式必须与第一张图片相同,否则报错。

alpha, 混合的因子。一般传入一个0~1的浮点数,如果alpha等于0.0,混合结果为第一张图片,如果alpha等于1.0,混合结果为第二张图片。如果alpha为0~1之间的数,则混合的图片out=im1*(1.0-alpha) + image2*alpha,效果为两张图片的叠加。如果传入其他值,则混合出来的图片效果比较混乱。

六、图片的复合

from PIL import Image


duck1 = Image.open('duck1.png')
duck2 = Image.open('duck2.png')
r, g, b, a = duck2.split()
image_compo = Image.composite(duck1, duck2, r)
image_compo.show()

运行结果:

composite(image1, image2, mask): 将两张图片复合成一张图片,使用蒙版。composite()是Image模块中的一个函数,不是Image类中的方法,有3个参数。

image1, 复合的第一张图片。

image2, 复合的第二张图片。图片的尺寸和模式必须与第一张图片相同,否则报错。

mask, 蒙版。也是一张图片,这张图片的模式为'1', 'L'或'RGBA',尺寸必须与前两张图片相同。

此方法其实是将第一张图片粘贴到第二张图片上,相当于image2.paste(image1, None, mask),可以参考Image类中paste()方法的用法。

七、图片的旋转

from PIL import Image


duck1 = Image.open('duck1.png')
print(duck1.size)
image = duck1.rotate(15, center=(0, 0), expand=1, translate=(100, 100), fillcolor=(0, 0, 255))
print(image.size)
image.show()

运行结果:

(1200, 800)
(1367, 1084)

rotate(angle, resample=NEAREST, expand=0, center=None, translate=None, fillcolor=None): 对图片进行旋转,返回一张旋转后的图片副本。有6个参数。

angle, 旋转的角度。这个参数是一个必传参数,按角度制计算,按逆时针方向旋转。

resample, 重采样,是一个可选的重采样过滤器。可以传入Image.NEAREST, Image.BILINEAR, Image.BICUBIC。默认为Image.NEAREST。如果图像的模式为'1'或'P',则始终设置为Image.NEAREST。

expand, 可扩展性。传入数字0或1,表示布尔值,默认为0。如果值为0,对图片旋转后,返回图片的尺寸与原图尺寸一样。如果值为1,则旋转后,返回图片的尺寸会根据旋转角度自动调整(如果旋转中心保持默认和没有进行平移,则返回图片中可以看到完整的原图)。

center, 旋转的中心。传入长度为2的元组(x, y),表示旋转中心的像素点。默认为原图的几何中心。

translate, 平移的坐标。传入长度为2的元组(x, y),将原图按(x, y)进行平移,默认为(0, 0)。

fillcolor, 填充颜色。传入一个颜色值,颜色值可以是元组表示法,也可以是颜色的十六进制表示法或颜色英文。如上面的(0, 0, 255)可以换成'#0000FF'或'blue'。当图片旋转后,原图变斜了,但返回图片还是矩形的,所以空出的部分需要进行填充,默认为黑色。

八、图片的转置和翻转

from PIL import Image


image = Image.open("yazi.jpg")
image1 = image.transpose(Image.FLIP_LEFT_RIGHT)
# image1.show()
image2 = image.transpose(Image.FLIP_TOP_BOTTOM)
# image2.show()
image3 = image.transpose(Image.ROTATE_180)
# image3.show()
image4 = image.transpose(Image.TRANSVERSE)
image4.show()

运行结果:

transpose(method): 转置或翻转图片,返回转置后的图片副本。method可以传入Image.FLIP_LEFT_RIGHT, Image.FLIP_TOP_BOTTOM, Image.ROTATE_90, Image.ROTATE_180, Image.ROTATE_270, Image.TRANSPOSE, Image.TRANSVERSE。这些方法都是旋转90度和翻转组合的结果。

九、改变图片的像素点位置

from PIL import Image


image = Image.open("yazi.jpg")
image_effect = image.effect_spread(7)
image_effect.show()

运行结果:

effect_spread(distance): 随机改变图片中像素点的位置,返回处理后的图片副本。将每个像素点随机移动到指定距离范围内的另一个点,distance表示每个像素点的随机变化距离,处理后的图片有“粒度”的变化。

在Image模块中,还有很多对图片处理的方法和函数,如有一组以get和put开头的方法,用于获取或修改图片的属性,有将图片与字节等互相转换的方法,有对动图的处理方法等。这里就不继续一一介绍了,感兴趣可以看看源码和官方文档,并多做尝试。

 

 

  • 14
    点赞
  • 80
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小斌哥ge

非常感谢,祝你一切顺利。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值