Pillow中最重要的类就是Image,该类存在于同名的模块中。可以通过以下几种方式实例化:从文件中读取图片,处理其他图片得到,或者直接创建一个图片。

还有一个类为ImageDraw,用来画图。

1、Image.alpha_composite(im1,im2)

将im2复合到im1上,返回一个Image对象

参数:im1--第一个图像

im2--第二个图像 im1和im2的size要相同。且im1和im2的mode都必须是RGBA

#!coding=utf-8
from PIL import Image
img1=Image.new("RGBA",(100,100),"red")
img2=Image.new("RGBA",(100,100),"yellow")
img3=Image.alpha_composite(img1,img2)
img3.show

结果为:

(python)图片处理Pillow模块的使用-LMLPHP

2、Image.blend(im1,im2,alpha)

返回回一个融合后的Image对象,得到的Image由im1和im2决定。:公式:out=im1*(1-alpha)+im2*alpha

参数:im1--第一个图像

im2--第二个图像 im1和im2的size要相同。

alpha-- 如果 alpha = 0.0, 第一个图像返回. 如果alpha =1.0, 第2个图像返回.alpha没有严格的值,如果有必要,就设置成刚好合适的范围内。

例子:

#!coding=utf-8
from PIL import Image
path="E:\\study\\test.png"
img1=Image.open(path)
img2=Image.new("RGB",img1.size,"red")
img3=Image.blend(img1,img2,0.5) #img1和img2的size要相同,不然会引起一个ValueError
img3.show()

 img1在合并img2前的图片为:

(python)图片处理Pillow模块的使用-LMLPHP

img1和img2合并后,得到的img3为:

(python)图片处理Pillow模块的使用-LMLPHP

3、PIL.Image.composite(im1,im2,mask)

通过使用透明遮罩混合图像创建复合图像。

参数:im1--第一个图像

im2--第二个图像 im1和im2的size和mode必须相同。

mask--也是一个图像,mode 可以为“1”, “L”, or “RGBA”,并且大小要和im1、im2一样

#!coding=utf-8
from PIL import Image
from PIL import ImageDraw
path1="E:\\study\\test.png"
img1=Image.open(path1)
img2=Image.new("RGB",img1.size,"blue")
img3=Image.new("RGBA",img1.size,"black")
img4=Image.composite(img1,img2,img3)
img4.show()

得到的结果:

(python)图片处理Pillow模块的使用-LMLPHP

其他例子:

例子1:画一个蓝底的图片,图片中有一个红色的圆

#! coding=utf-8
from PIL import Image
from PIL import ImageDraw
path="E:\\study\\yy.png" #文件存储的路径
image=Image.new("RGB",(200,200),"blue")#创建一个蓝色的,大小为200*200像素的RGB图片
drawObject=ImageDraw.Draw(image)
drawObject.ellipse((50,50,80,80),fill="red")#在image上画一个红色的圆
image.save(path)#保存图片
"""以下代码用来显示出画的图片"""
try:
img=Image.open(path)
img.show()#标准版本的show()方法不是很有效率,因为它先将图像保存为一个临时文件,然后使用xv进行显示。如果没有安装xv,该函数甚至不能工作。但是该方法非常便于debug和test。(windows中应该调用默认图片查看器打开)
except IOError,e:
print e.message

  结果图片展示结果:

(python)图片处理Pillow模块的使用-LMLPHP

例子2:将QQ 头像(或者微博头像)右上角加上一个圆形红色底的白色数字,类似于微信未读信息数量那种提示效果。

#! coding=utf-8
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
path="E:\\study\\test.png" #文件存储的路径
path2="E:\\study\\test2.png"
Font3 = ImageFont.truetype("C:\Windows\Fonts\simsunb.ttf",20)
text="3"
img=Image.open(path)
box1=(55,0,75,20)
drawObject=ImageDraw.Draw(img)
drawObject.ellipse(box1,fill="red")
drawObject.text([60,2],text,fill="white",font=Font3)#写入文字3
img.save(path2)
"""以下代码用来显示出画的图片"""
try:
image=Image.open(path2)
image.show()#标准版本的show()方法不是很有效率,因为它先将图像保存为一个临时文件,然后使用xv进行显示。如果没有安装xv,该函数甚至不能工作。但是该方法非常便于debug和test。(windows中应该调用默认图片查看器打开)
except IOError,e:
print e.message

结果图片显示结果:

(python)图片处理Pillow模块的使用-LMLPHP

相关函数如下:

一、Image Module(from PIL import Image)

Image.open(fp)--fp可以是文件名,也可是file object,但是必须是以'r'模式打开的。最后返回一个Image 对象

Image.blend(im1,im2,alpha) --返回一个融合后的Image对象,out=im1*(1-alpha)+im2*alpha

Image.composite(im1,im2,mask)--返回一个融合后的Image对象,out由透明遮罩mask和原始im1,im2决定,mask模式为'1','L'或'RGBA'

L模式下:out=im1*L/255+im2*(1-L/255)

RGBA模式下:out=im1*mask+im2*(1-mask),mask的值由mask图像在该点是否为空及alpha值决定

--使用RGBA模式的mask(ImageDraw画出矩形或圆形等局部图形)可以实现局部透明度的变化

blend方法要想实现局部透明度变化只能crop,paste

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

Image.new(mode,size,color=0) --创建一个新对象,mode为单通道时,color为一个整数或浮点数;

多通道时,color为元组,元素数目对应通道数。

Image.fromarray(obj,mode=None) --从含有array interface 的其他对象创建Image对象

Image.merge(mode,bands) --融合多个通道图像

Image 对象的属性(im=Image.open(fp))

im.mode--如'L','RGB'等

im.size--(200,300)

im.format --如'JPEG'

im.info 、im.palette

Image 对象的方法(im=Image.open(fp))

im.convert(mode)--转换模式,如'L','RGB'

im.copy() --复制,不影响原图像

im.crop(box) --复制一部分图像,box为一个元组,定义矩形的左上角和右下角。改变原图像,可能会也可能不会影响crop的部分,

如果想使复制的部分脱离原图像的影响,对crop后的部分采用load方法

im.getbands() --返回一个包含各通道名称的元组

im.getbbox() --返回非空边界矩形,左上点和右下点

im.getdata() --返回一个扁平化的图像像素序列(PIL内在类型),之后需要使用list()方法将其转化为python语言的序列

im.getextrema() --返回每个通道中像素值得(min,max)值

im.getpixel((x,y)) --返回(x,y)处的像素值

im.histogram() --返回直方图统计数据

im.paste(im1,box=None)--将im1粘贴到im上,box默认为None,表示从(0,0)开始粘贴,也可以设置为其他二元元组或四元元组

设置为四元元组时,im1的大小必须和box表示的矩形大小一样。另外,'RGBA'模式的alpha将被忽视

im.resize(size,resample=0) --调整大小,resample有四个选项,默认为第一个,第四个质量更高一些

Image.NEAREST:nearest neighbour

Image.BILINEAR:linear interpolation

Image.BICUBIC:cubic spline interpolation

Image.LANCZOS:a high-quality downsa

mpling filter

im.rotate(degrees,resample=0,expand=0) --逆时针旋转某一度数,resample有三个选项,默认第一个;expand默认为0,

保持旋转后图像和原来大小相同,超出边界的部分舍掉,设置为True则扩展图像大小以保证能全部显示原图像的内容

im.save(fp,format=None) --保存图像

im.show(title=None) --调试时常用来显示图像

im.split() --分离通道,返回分离后的通道元组

im.transpose(method)--旋转图像,method有:Image.FLIP_LEFT_RIGHT 左右颠倒

Image.FLIP_TOP_BOTTOM 上下颠倒

Image.ROTATE_90 逆时针旋转90度

Image.ROTATE_180 逆时针旋转180度

Image.ROTATE_270 逆时针旋转 270度

Image.TRANSPOSE 上下左右颠倒

im.load() --分配图像存储空间,载入像素数据,一般open得到的对象会自动调用,无需手动调用

因为此方法会使图像对象和原文件断绝联系,故在im.crop()后可用于切断复制部分与原图像的联系

二、ImgaeFont Module (from PIL import ImageFont)

ImageFont.load(filename) --加载字体文件,返回一个font对象

ImageFont.load_path(filename) --加载字体文件,会沿着Python Path寻找

ImageFont.truetype(font=None,size=10,index=0) --加载TrueType或opentype类型的字体文件,返回一个size大小的font对象

当前目录没有该文件则去windows的fonts目录下查找

index决定加载哪个font face(一个字体文件可能会包含多个相关的字体)

ImageFont对象方法(font=ImageFont.load(f)):

font.getsize(text)--返回text在当前字体下的大小

3.ImageColor Module (from PIL import ImageColor)

ImageColor.getrgb(color) --将字符串形式的color转换为rgb的形式,即(r,g,b[,a])

ImageColor.getcolor(color,mode) --将字符串形式的color转换为rgb或greyscale的形式

mode是color(如’RGB'),则返回(r,g,b[,a]);不是color(如'L')则返回(graylevel[,a])

该模块支持的color字符串的形式有以下几种:

(1)十六进制形式,#rgb或者#rrggbb,如#00ff00,#0b1

(2)RGB Function,如rgb(255,0,0)或者rgb(100%,0%,20%)

(3)HSL模式,如hsl(0,20%,100%),hsl(360,0%,100%)

(4)HTML颜色,如'red','Red'

三、ImageDraw Module (from PIL import ImageDraw)

ImageDraw.Draw(im) --返回一个绘图对象,使以后的绘图操作发生在im上

Draw对象方法(draw=ImageDraw.Draw(im)):

注:无特殊说明,参数box类型默认为[x,y,x,y]或[(x,y),(x,y)];xy参数类型默认为[x,y,x,y,x,y...]或者[(x,y),(x,y),(x,y),...]

draw.arc(box,start,end,fill=None) --start定义起始角度(0代表3点钟方向),end定义终止角度,都为degrees,正方向为顺时针。

draw.chord(box,start,end,fill=None,outline=None) --类似arc,但是连接首尾端

点,fill为填充颜色,outline为描边颜色

draw.ellipse(box,fill=None,outline=None) --画一个椭圆

draw.line(xy,fill=None,width=0) --直线

draw.pieslice(box,start,end,fill=None,outline=None) --画一个扇形

draw.points(xy,fill=None) --点

draw.polygon(xy,fill=None,outline=None) --画一个多边形

draw.rectangle(box,fill=None,outline=None) --矩形

draw.text(xy,text,fill=None,font=None) --xy为左上点位置,font为ImageFont对象

draw.textsize(text,font=None) --返回text在font字体下的大小

05-04 00:56