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
结果为:
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前的图片为:
img1和img2合并后,得到的img3为:
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()
得到的结果:
其他例子:
例子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
结果图片展示结果:
例子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
结果图片显示结果:
相关函数如下:
一、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字体下的大小