Pillow

模块介绍

Pillow是PIL的一个派生分支,但如今已经发展成为比PIL本身更具活力的图像处理库。pillow可以说已经取代了PIL,将其封装成python的库(pip即可安装),且支持python2和python3,目前最新版本是3.0.0。


常用功能

在日常应用过程中,使用最多的是 pillow 提供的 Image 模块,其提供了包括图像存储、变换以及一系列的相关处理功能。pillow 模块中的 ImageDraw 类提供了一系列绘图方法,ImageGrab 模块则提供了将屏幕或剪贴板的内容复制到 PIL 图像内存的功能。通常,使用下面的方法,导入 pillow 的一个或多个子模块如下:

from PIL import Image, ImageDraw, ImageGrab 

打开图像文件

>>> im = Image.open(r'D:python_counselor.jpg')
>>> im.show() # show()方法会自动调用系统默认的图像查看工具显示图像

保存图像文件

>>> im = Image.open(r'D:python_counselor.jpg')
>>> im.save(r'D:python_counselor.bmp') # 读出.jpg文件,可以直接保存为.bmp文件

创建空白图像

>>> im = Image.new("RGBA", (320, 240), color=(0,255,255,128)) # 新建320x240的半透明青色背景的图片
>>> im.show()

图像模式转换

>>> im = Image.open(r'D:python_counselor.jpg')
>>> im.mode # 查看图像模式
'RGB'
>>> im_gray = im.convert('L') # 将RGB彩色模式转为灰度模式
>>> im_gray.show()

convert() 是图像实例对象的一个方法,接受一个 mode 参数,用以指定一种色彩模式,mode 的取值可以是如下几种:
· 1 (1-bit pixels, black and white, stored with one pixel per byte)
· L (8-bit pixels, black and white)
· P (8-bit pixels, mapped to any other mode using a colour palette)
· RGB (3x8-bit pixels, true colour)
· RGBA (4x8-bit pixels, true colour with transparency mask)
· CMYK (4x8-bit pixels, colour separation)
· YCbCr (3x8-bit pixels, colour video format)
· I (32-bit signed integer pixels)
· F (32-bit floating point pixels)


通道合并与拆分

>>> im = Image.open(r'D:Transp400.png')
>>> im.mode # # png格式的图像有4个通道
'RGBA'
>>> im_rgb = im.convert('RGB') # 固然可以使用convert()将RGBA模式转换为RGB模式
>>> r,g,b,a = im.split() # 还可以将RBGA图像拆分成独立的4个通道
>>> im_rgb = Image.merge("RGB",(r,g,b)) # 在按照需要合并成目标模式
>>> im_rgb.show()

>>> im_rgb = Image.merge("RGB",(b,g,r)) 
>>> im_rgb.show()

图像缩放

>>> im = Image.open(r'D:Transp400.png')
>>> im.size # 查看图像大小
(400, 400)
>>> im_100 = im.resize((100,100)) # 改变图像大小(无需保持比例),返会新的Image对象
>>> im_100.size
(100, 100)
>>> im_100.show()
>>> im.thumbnail((128,128)) # 生成缩略图,但不会返回新的Image对象,而是直接改变了原对象的大小
>>> im.show()


图像旋转

图像旋转的函数原型如下

Image.rotate(angle, =0, expand=0, center=None, translate=None)

angle – 单位度(°),逆时针方向为正

resample – 可选的重采样过滤器,选项:Image.NEAREST,Image.BILINEAR,Image.BICUBIC

expand – 可选的扩展标记。如果为真,则展开输出图像,使其足够大以容纳整个旋转后的图像。如果为假或省略,使输出图像的大小与输入图像相同。请注意,扩展标志假定是围绕中心旋转的,没有平移

center – 可选的旋转中心(2元组),默认是图像的中心

translate – 一个可选的旋转后转换(2元组)

>>> im = Image.open(r'D:Transp400.png')
>>> im_rotate = im.rotate(-50)
>>> im_rotate.show() # 以图片中心为基点顺时针旋转50度
>>> im_rotate = im.rotate(-50, expand=True, center=(100,100), translate=(100,00))
>>> im_rotate.show() # 以(100,100)为基点顺时针旋转50度后右移100像素


图像复制,裁剪与粘贴

>>> im_bg = Image.open(r'D:python_op.png')
>>> im_bg.size
(800, 404)
>>> im_bg.show()
>>> im = Image.open(r'D:Transp400.png')
>>> im.size
(400, 400)
>>> im_box = im.crop((50,50,250,250)) # 图像裁切位置:左上(50,50),右下(250,250)
>>> im_box.size
(200, 200)
>>> im_copy = im_box.copy() # 图像复制
>>> im_bg.paste(im_copy, (400,0)) # 图像粘贴,位置(400,0)
>>> im_bg.paste(im, (0,0)) # 图像粘贴,位置(0,0)
>>> im_bg.show()


使用滤镜

ImageFilter模块包含一组预定义的滤镜,可以与Image.filter()方法一起使用。这些滤镜包括:

from PIL import Image, ImageFilter 
im = Image.open(‘1.png’) 
# 高斯模糊 
im.filter(ImageFilter.GaussianBlur) 
# 普通模糊 
im.filter(ImageFilter.BLUR) 
# 边缘增强 
im.filter(ImageFilter.EDGE_ENHANCE) 
# 找到边缘 
im.filter(ImageFilter.FIND_EDGES) 
# 浮雕 
im.filter(ImageFilter.EMBOSS) 
# 轮廓 
im.filter(ImageFilter.CONTOUR) 
# 锐化 
im.filter(ImageFilter.SHARPEN) 
# 平滑 
im.filter(ImageFilter.SMOOTH) 
# 细节 
im.filter(ImageFilter.DETAIL)
>>> im = Image.open(r'D:hello.jpg')
>>> im.show() 
>>> im.filter(ImageFilter.BLUR).show() 
>>> im.filter(ImageFilter.FIND_EDGES).show() 
>>> im.filter(ImageFilter.CONTOUR).show() 


绘图

>>> im_bg = Image.open(r'D:python_op.png')
>>> font = ImageFont.truetype("arial.ttf", 32)
>>> draw = ImageDraw.Draw(im_bg)
>>> draw.line((0, im.size[1], im.size[0], 0), fill=(255, 255, 255, 255)) # 绘制值线,[(x, y), (x, y), ...] or [x, y, x, y, ...]
>>> draw.arc([60,60,200,200], 0, 270, fill='red') # 绘制圆弧,box, start angle, end angle, fill color
>>> draw.rectangle([300,300,500,400], fill='red', outline='white') # 绘制矩形
>>> draw.point([60,60,62,60,64,60,66,60,68,60,70,60],fill='white') # 绘制点, [x, y, x, y, x, y]
>>> draw.text([400, 300], "Hello, world", font=font) # 绘制文字
>>> im_bg.show()


截取屏幕

>>> im = ImageGrab.grab((1200,600,1920,1080)) # 截取屏幕范围:左上角(1200,600),右下角(1920,1080)
>>> im.show()


图像对比度增强

from PIL import Image  
from PIL import ImageEnhance  

#原始图像  
image = Image.open('lena.jpg')  
image.show()  

#亮度增强  
enh_bri = ImageEnhance.Brightness(image)  
brightness = 1.5  
image_brightened = enh_bri.enhance(brightness)  
image_brightened.show()  

#色度增强  
enh_col = ImageEnhance.Color(image)  
color = 1.5  
image_colored = enh_col.enhance(color)  
image_colored.show()  

#对比度增强  
enh_con = ImageEnhance.Contrast(image)  
contrast = 1.5  
image_contrasted = enh_con.enhance(contrast)  
image_contrasted.show()  

#锐度增强  
enh_sha = ImageEnhance.Sharpness(image)  
sharpness = 3.0  
image_sharped = enh_sha.enhance(sharpness)  
image_sharped.show()

验证码

from PIL import Image, ImageDraw, ImageFont, ImageFilter

import random

# 随机字母:
def rndChar():
    return chr(random.randint(65, 90))

# 随机颜色1:
def rndColor():
    return (random.randint(64, 255), random.randint(64, 255), random.randint(64, 255))

# 随机颜色2:
def rndColor2():
    return (random.randint(32, 127), random.randint(32, 127), random.randint(32, 127))

# 240 x 60:
width = 60 * 4
height = 60
image = Image.new('RGB', (width, height), (255, 255, 255))
# 创建Font对象:
font = ImageFont.truetype('Arial.ttf', 36)
# 创建Draw对象:
draw = ImageDraw.Draw(image)
# 填充每个像素:
for x in range(width):
    for y in range(height):
        draw.point((x, y), fill=rndColor())
# 输出文字:
for t in range(4):
    draw.text((60 * t + 10, 10), rndChar(), font=font, fill=rndColor2())
# 模糊:
image = image.filter(ImageFilter.BLUR)
image.save('code.jpg', 'jpeg')

如果运行的时候报错:

IOError: cannot open resource

这是因为PIL无法定位到字体文件的位置,可以根据操作系统提供绝对路径,比如:

'/Library/Fonts/Arial.ttf'
原文地址:https://www.cnblogs.com/kai-/p/13061994.html