python3之成像库pillow

python提供了python image library图像库,处理图像功能,该库提供了广泛的文件格式支持,如JPEG、PNG、GIF、等,它提供了图像档案、图像显示、图像处理等功能

PIL中所涉及到的基本概念包括,(bands)通道,(mode)模式,(coordinate system)坐标系统,(palette)调色板,(filters)过滤器

每张图像都是由一个或者多个数据通道构成,PIL可以在单张图片中合成相同维数和深度的多个通道,如RGB有三个通道,而灰度图像则只有一个通道

图像实际上是像素数据的矩形图,图像的模式定义了图像中像素的类型和深度,它在图像中定义mode模式的概念,如:

  • 1:1位像素,表示黑和白,占8bit,在图像表示中称为位图
  • L:表示黑白之间的灰度,占8bit像素
  • p:8位像素,使用调色版映射
  • RGB:为真彩色,占用3x8位像素,其中R为red红色,G为green绿色,B为blue蓝色,三原色叠加形成的色彩变化,如三通道都为0则代表黑色,都为255则代表白色
  • RGBA:为带透明蒙版的真彩色,其中的A为alpha透明度,占用4x8位像素

其他的还有打印分色CMYK不是很常用不多做介绍

 PIL使用笛卡尔像素坐标系统,图像的坐标从左上角开始(0,0),坐标值表示像素的角,它实际上位于(0.5,0.5);python中坐标通常以2元组(X,Y)的形式传递,矩形表示为4元组(l_x,t_y,r_x,b_y),X轴从左到右,Y轴从上到下,顺序是从左上右下表示,从左上角开始,如一个800X600像素的图像矩形表示为(0,0,800,600),它实际上时左上角锁定,向右下延伸的。

PIL的安装:

pip3 install pillow

1、图像模块(Image.Image)

图像模块提供PIL名称的类,该模块提供了许多功能,包括文件加载和创建新图像等,下面我们创建一个图像对象,然后旋转图像90度并显示:

from PIL import Image

im=Image.open("78525.jpg")
im.rotate(90).show()

批量创建缩略图脚本,在文件夹下批量创建128x128的缩略图:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/7/9 16:40
# @Author  : Py.qi
# @File    : test1.py
# @Software: PyCharm
from PIL import Image
import glob,os

size=128,128
for infile in glob.glob('D:\image\*.jpg'):
    filename=os.path.split(infile)[-1]
    im=Image.open(infile)
    im.thumbnail(size,Image.ANTIALIAS)
    im.save("E:\images\\"+filename)   #注意保存图像时按照比例缩放保存的,以最大像素为依据比例缩小

(1)Image模块的功能

Image.new(mode,size,color):

使用给定的模式、大小和颜色创建新图像;大小以(宽度,高度)2 元组的形式给出,以像素为单位;颜色以单波段图像的单个值和多波段图像的元组(每个波段的一个值)给出,可以使用颜色名如‘red’也可以受用16进制#FF0000或者使用数字表示(255,0,0)

from PIL import Image

#这三种效果一样,都为分辨率1920x1080的红色图像
im = Image.new('RGB',(1920,1080),(255,0,0))
im1 = Image.new('RGB',(1920,1080),'red')
im2 = Image.new('RGB',(1920,1080),'#FF0000')
im.show()
im1.show()
im2.show()

Image.open(file,mode):读取图像文件头,mode只能是‘r’

from PIL import Image
from io import BytesIO
import requests

#打开文件或从文件流中打开图像
im=Image.open('path/to/imagefile.jpg')
r=requests.get('http://image.jpg')
im1=Image.open(BytesIO(r.content))
from PIL import Image

#将图像转换为PNG
im=Image.open('images/22.jpg','r')
im.save('images/33.png')
#im.show()
im_png=Image.open('images/33.png','r')
print(im_png.format)

#
PNG

Image.blend(image1,image2,alpha):通过使用常量alpha在给定图像之间进行差值来创建新图像,两个图像必须具有相同的大小和模式,aplha为0则返回第一张图像的拷贝,为1则返回第二张图像的拷贝,可以去中间值来划分偏差如0.5

from PIL import Image

image1=Image.new('RGB',(1920,1080),(0,0,255))  #蓝色图像
image2=Image.new('RGB',(1920,1080),(255,0,0))  #红色图像
im=Image.blend(image1,image2,0.5)  #取中间值
image1.show()
image2.show()
im.show()  #显示紫色图像,因为红色叠加蓝色会调和成紫色
im.save('5555.jpg')

Image.composite(image1,image2,mask):通过给定的图像之间进行差值,使用mask图像的响应像素作为alpha来创建新图像,mask可以具有的模式‘1’,‘L’,或者‘RGBA’

image1=Image.new('RGB',(1920,1080),(0,0,255))  #蓝色图像
image2=Image.new('RGB',(1920,1080),(255,0,0))  #红色图像
image3=Image.new('L',(1920,1080),125)  #灰色

im=Image.composite(image1,image2,mask=image3)
image1.show()
image2.show()
image3.show()
im.show() 
im.save('5555.jpg')   

Image.eval(image,function):function为接受一个整数参数的函数,将im的每个像素值分别传给func处理并返回最后的Image对象

from PIL import Image

im = Image.open('31.gif')
evl = Image.eval(im,lambda x:x/2)  #将每个像素除以2
evl.show()

Image.merge(mode,bands):从多个单通道创建新图像,bands为图像的元组或列表

from PIL import Image

im1=Image.open('1.jpg').resize((1024,768),Image.ANTIALIAS) #type:Image.Image
im2=Image.open('2.jpg').resize((1024,768),Image.ANTIALIAS) #type:Image.Image
im3=Image.open('5555.jpg').resize((1024,768),Image.ANTIALIAS) #type:Image.Image
im1_rgb=im1.split()
im2_rgb=im2.split()
im3_rgb=im3.split()
rgbs=[im1_rgb[0],im2_rgb[1],im3_rgb[2]] #使用三个图像的单通道
im_merge=Image.merge('RGB',rgbs) #合成一张新图像
im_merge.show()
print(im_merge.size,im_merge.mode)

(2)Image模块的方法

Image类的实例具有以下方法,所有方法都会返回Image类的新实例,并保留生成的图像

im.convert(mode):将图像转换为另一种模式,然后返回新图像

from PIL import Image

image1=Image.open('1.jpg')
assert isinstance(image1,Image.Image)
img1=image1.convert('L')   #将图像转换为灰色
img1.show()

im.copy():拷贝图像

im.crop(box):从当前图像返回矩形区域的副本,box是一个4元祖,定义从左、上、右、下的像素坐标

#剪切图像
box=(100,100,400,400) #定义了图像的坐标位置,从左、上、右、下
im=Image.open('images/22.jpg','r')
print(im.size)
region=im.crop(box)  #它会从左上角开始,同时向下和向右移动100像素的位置开始截取400-100的像素宽高,也就是300x300的图像
print(region.size)
region.save('images/300x300.jpg')

im.filter(filter):返回由给定过滤器过滤的图像的副本

im.getbands():返回包含每个band的名称的元组。例如, RGB图像上的getband返回(“R”,“G”,“B”)

from PIL import Image
im=Image.open('1.jpg')
im1=Image.new('L',(1080,1050),100)
assert isinstance(im,Image.Image)
print(im1.getbands())
print(im.getbands())
im1.show()

#
('L',)
('R', 'G', 'B')

im.getbbox():计算图像中非零区域的边界框

from PIL import Image
im=Image.open('1.jpg')
im1=Image.new('L',(1080,1050),100)
assert isinstance(im,Image.Image)
print(im.getbbox())
print(im1.getbbox())

#
(0, 0, 1229, 768)
(0, 0, 1080, 1050)

im.getcolors(maxcolors):返回元祖的末排序列表

from PIL import Image
im=Image.open('1.jpg')
im1=Image.new('L',(1080,1050),100)
assert isinstance(im,Image.Image)
print(im.getcolors())
print(im1.getcolors()) #返回计数和颜色的元组

#
None
[(1134000, 100)]

im.getdata():将图像的内容作为包含像素值的序列对象返回

im.getextrema():返回包含图像最小值和最大值的2元组,仅适用于单波段图像

im.getpixel(xy):返回给定位置的像素。如果图像是多层图像,则此方法返回元组

from PIL import Image

im=Image.open('1.jpg')
im1=Image.new('L',(1080,1050),100)
assert isinstance(im,Image.Image)
print(list(im.getdata()))  #返回图像的像素值列表
print(im.getextrema()) #返回图像的最小和最大值元组
print(im.getpixel((15,15))) #返回给定位置的像素元组

#
14, 233), (205, 210, 229), (209, 212, 229)......
((0, 255), (0, 255), (0, 255))
(10, 59, 76)

im.load():映像分配存储并从文件加载它

im.point(table):返回图像的副本,其中每个像素已通过给定的查找表进行映射

from PIL import Image

im=Image.open('1.jpg')
assert isinstance(im,Image.Image)
#调整灰色图像的对比度
im_point=im.convert('L').point(lambda i:i < 80 and 255)
im_point.show()
source=im.split()
#三通道分别处理对比度
mask_r=source[0].point(lambda i:i < 80 and 255)
mask_g=source[1].point(lambda i:i < 80 and 255)
mask_b=source[2].point(lambda i:i < 80 and 255)
mask_r.show()
mask_g.show()
mask_b.show()

im.resize(size,filter=None):返回图像的已调整大小的副本

from PIL import Image

#filter为滤波器:将多个输入像素映射为一个输出像素的几何操作,PIL提供的采样滤波器:
#NEAREST:最近滤波。从输入图像中选取最近的像素作为输出像素。它忽略了所有其他的像素
#BILINEAR:双线性滤波。在输入图像的2x2矩阵上进行线性插值,,做下采样时该滤波器使用了固定输入模板
#BICUBIC:双立方滤波。在输入图像的4x4矩阵上进行立方插值,做下采样时该滤波器使用了固定输入模板
#ANTIALIAS:平滑滤波,对所有可以影响输出像素的输入像素进行高质量的重采样滤波,以计算输出像素值,这个滤波器只用于改变尺寸和缩略图方法
#ANTIALIAS滤波器是下采样,将大图转换为小图或左缩略图时唯一正确的滤波器,BILIEAR和BICUBIC滤波器使用固定的输入模板,用于固定比例的几何变换和上采样是最好的

im=Image.open('1.jpg') #type:Image.Image
print(im.size)
img1=im.resize((1024,768),Image.BILINEAR)
img2=im.resize((1024,768),Image.BICUBIC)
img3=im.resize((1024,768),Image.ANTIALIAS)
img4=im.resize((1024,768),Image.NEAREST)
im.show()
img1.show()
img2.show()
img3.show()
img4.show()

im.rotate(angle):返回围绕其中心逆时针旋转给定度数的图像副本

from PIL import Image

image1=Image.open('1.jpg')
assert isinstance(image1,Image.Image) #pycharm定义实例类
img1=image1.resize((1680,1050)) #返回跳转图像尺寸的副本
img1.show()
img2=img1.rotate(90)   #逆时针旋转图像90度
img2.show()

im.save(outfile,format,options):将图像保存在给定的文件名下

im.seek(frame):寻找序列文件中的给定帧

im.show():显示图像

im.split():返回图像中各个图像带的元组

from PIL import Image
im=Image.open('1.jpg')
assert isinstance(im,Image.Image)
source=im.split()  #分隔RGB三通道颜色的副本
print(source)
source[0].show() 
source[1].show()
source[2].show()

#
(<PIL.Image.Image image mode=L size=1229x768 at 0xE8D3ADACC0>, <PIL.Image.Image image mode=L size=1229x768 at 0xE8D3AE9048>, <PIL.Image.Image image mode=L size=1229x768 at 0xE8D3AE9080>)

im.tell():返回当前帧编号

im.thumbnail(size):修改图像以包含其自身的缩略图版本

from PIL import Image

size=(128,128)
im=Image.open('images/31.gif','r')
print(im.size)
im.thumbnail(size)   #它会根据图像的宽高比例缩小,以最大的值为标准
im.save('images/55.gif','GIF')
print(im.size,im.format)


#
(275, 434)
(81, 128) GIF

im.paste(image,box):将另一张图像粘贴到此图像中

im.transpose(method):返回图像的翻转或旋转副本

from PIL import Image

#剪切和粘贴图像
box=(100,100,400,400) #定义了图像的坐标位置,从左、上、右、下
im=Image.open('images/162.jpg')
print(im.size)
region=im.crop(box)  #它会从左上角开始,同时向下和向右移动100像素的位置开始截取400-100的像素宽高,也就是300x300的图像
print(region.size)
#region.save('images/500x500.jpg')

region_tran180=region.transpose(Image.ROTATE_180) #旋转图像180度

im.paste(region_tran180,box)  #按照像素比例粘贴回去

im.verify():尝试确定文件是否损坏,而不实际解码图像数据

im.format:源文件的文件格式

im.mode:图像模式典型值为“1”,“L”,“RGB”或“CMYK”

im.size:图像大小,以像素为单位。大小以2元组(宽度,高度)给出

im.palette:调色板表

im.info:保存与图像相关的数据的字典

#!/usr/bin/env python
#coding:utf-8
from PIL import Image

#从文件中加载图像
im=Image.open("images/22.jpg")
print(im.format)   #显示图像类型
print(im.size)   #显示图像的宽度和高度,像素为单位的2元祖
print(im.mode)  #显示图像属性中波段的数量和名称,以及像素类型和深度,常见模式有灰色图像"L"表示亮度,真彩色图像的"RGB"和印刷图像模式“CMYK”
im.show()  #调用程序显示图像

#
JPEG
(1024, 768)
RGB

2、ImageChops模块

ImageChops模块包含多个算术图像的操作,称为通道操作,它们可以实现,特殊效果,图像合成,算法绘画等

它的功能大多数通道操作都是采用一个或两个图像参数比较来返回一个新图像,下面只列出一些常用的方法:

IC.lighter(image1,image2):逐个像素地比较两个图像,并返回包含较亮值的新图像

from PIL import Image
from PIL import ImageChops
im1=Image.open('1.jpg')
im2=Image.open('2.jpg')

IC_image=ImageChops.lighter(im1,im2)
IC_image.show()

IC.darker(image1,image2):逐个像素地比较两个图像,并返回包含较暗值的新图像

IC.difference(image1,image2):返回两个图像之间差异的绝对值

IC.multiply(image1,image2):将两个图像叠加在一起。如果将图像与纯黑色图像相乘,则结果为黑色。如果乘以纯白图像,则图像不受影响

IC.screen(image1,image2):将两个倒置的图像叠加在一起

IC.add(image1,image2,scle,offset):添加两个图像,按比例划分结果并添加偏移量

IC.subtract(image1,image2,scale,offset):减去两个图像,按比例划分结果并添加偏移量

3、ImageColor模块

ImageColor模块用来实现RGB颜色表转换,它支持是颜色格式包括:

  • 十六进制颜色说明符,例如,#ff0000指定纯红色
  • RGB函数,以“rgb(红色,绿色,蓝色)”给出,其中颜色值是0到255范围内的整数,如,“rgb(255,0,0)”和“rgb(100%,0%,0%)
  • 常见的HTML颜色名称,例如,“red”指定纯红色

 getrgb(color):将颜色字符串转换为RGB元组

from PIL import ImageColor
IC_image=ImageColor.getrgb('red')
print(IC_image)

#
(255, 0, 0)

 getcolor(color,mode):与getrgb相同,但如果模式不是颜色或调色板图像,则将RGB值转换为灰度值

更多内容参考官方手册:http://effbot.org/imagingbook/

Pillow只是个基础的图像处理库,若不深入图像处理,已够使用;专业人士都使用opencv

后面就开始搞验证码识别了!期待的小伙伴们点赞加关注哦,生命在于折腾.........

posted @ 2018-07-12 10:47  Py.qi  阅读(12930)  评论(2编辑  收藏  举报