通过Pillow库,可以方便的使用python程序对图片进行处理,例如常见的尺寸、格式、色彩、旋转等

安装pillow

pip install pillow

图像处理的基本知识

图像的RGB色彩模式

RGB三个颜色通道的变化和叠加得到的各种颜色,其中

-R红色,取值范围 0~255
-G绿色,取值范围0~255
-B蓝色,取值返回0~255

比如,我们常见的黄色就是由红色和绿色叠加起来的

红色的RGB表示(255,0,0) 绿色的RGB表示(0,255,0)
蓝色的RGB表示(0,0,255) 黄色的RGB表示(255,255,0)

像素阵列

数字图像可以看成一个整数阵列,阵列中的元素称为像素(Pixel)

每个点代表1个像素,一个点包含RGB三种颜色。也就是1个像素包含3个字节的信息:(R,G,B)假如这个像素是红色,则信息时:(255,0,0)。那么理论上我们只要操作每个点上的三个数字,就能实现任何图形,一幅图像上的所以偶像素点的信息就完全可以采用矩阵来表示,通过矩阵实现的运算实现跟家复杂的操作

Image模块

打开新建
open(fp,mode)

  1. fp:指打开文件的路径
  2. mode:可选参数,表示打开文件的方式,通常默认为r | mode(模式) | bands(通道) | 说明 | | —- | —- | —- | | “1” | 1 | 数字1,表示黑白二值图像,每个像素用0或1共1位二进制代码表示 | | “L” | 1 | 灰度图。每个像素用8位二进制代码表示 | | “P” | 1 | 索引图,每个像素用8位二进制代码表示 | | “RGB” | 3 | 24位真彩图,每个像素用3个字节的二进制代码表示 | | “RGBA” | 4 | “RGB”+透明通道表示,每个像素用4个字节的二进制代码表示 | | “CMYK” | 4 | 印刷模式图像,每个像素用4个字节二进制代码表示 | | “YCbCr” | 3 | 彩色视频颜色隔离模式,每个像素用3个字节的二进制代码表示 | | “LAB” | 3 | lab颜色空间,每个像素用3个字节的二进制代码表示 | | “HSV” | 3 | 每一个像素用3个字节的二进制代码表示 | | “I” | 1 | 使用整型形式表示像素,,每个像素用4字节的二进制代码表示 |
  1. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/1315343/1653686331424-3c7ad8a6-d4a4-4cd0-8aed-1d3933ea95e0.png#clientId=u29dba2da-3fa1-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=401&id=uc8729e52&margin=%5Bobject%20Object%5D&name=image.png&originHeight=501&originWidth=1330&originalType=binary&ratio=1&rotation=0&showTitle=false&size=59213&status=done&style=shadow&taskId=uf45857a0-b9aa-4706-87d1-372d5eec5b6&title=&width=1064)


from PIL import Image

#打开图片
img=Image.open('01.jpg')

#图片显示
img.show()


print('图片格式',img.format)
print('图片的大小',img.size)
print('图片的高度',img.height,'图片宽度',img.width)
print('获取(100,100)像素值:',img.getpixel((100,100)))

image.png


混合

透明度混合处理
blend(im1,im2,alpha)
其中im1、im2指参与混合的图片1与图片2,alpha指混合透明度,取值是0-1
通过使用函数blend()可以将im1和im2这两幅图片(尺寸相同),以一定的透明度进行混合。

(im1*(1-alpha)+im2*alpha)

当混合透明度为0时,显示im1图片。当混合透明度alpha取值为1时,显示im2原图片

from PIL import Image

img1=Image.open('01.jpg')

img2=Image.new('RGB',img1.size,'red').convert(mode='RGB')

Image.blend(img1,img2,alpha=0.2).show()

image.png


from PIL import Image

img1=Image.open('01.jpg')
img2=Image.open('02.jpg')
img1=img1.resize(img2.size)

r,g,b=img2.split()

Image.composite(img1,img2,b).show()

image.png

复制和缩放

  1. 复制图像

在Pillow库和Image模块中,可以使用函数Image.copy()复制指定的图片,用于在处理和粘贴时需要持有源图片

image.png

  1. 缩放像素

在Pillow库中Image模块中,可以使用函数eval()实现像素缩放处理,能够使用函数fun()计算输入图片的每个像素并返回。使用eval()语法格式如下:

eval(image,fun)

其中image表示输入的图片,fun表示给输入的图片每个像素应用次函数,fun()函数只允许接收一个整型参数。如果一个图片含有多个通道,则每个通道都会应用这个函数

from PIL import Image

#按图片缩放图片

img1=Image.open('02.jpg')


Image.eval(img1,lambda x:x*2).show()

image.png

  1. 缩放尺寸

Image.thmbnail(size,resample=3)

image.png

粘贴和裁剪

  1. 粘贴

Image.paste(im,box=None,mask=None)

其中im是源图或元素值,box是粘贴的区域,mask是遮罩。参数box可以分为以下三种情况

  • (x1,y1):将源图像左上角对齐(x1,y1)点,其余超出粘贴区域被抛弃
  • (x1,y1,x2,y2):源图像与此区域必须一致
  • None:源图像与被粘贴的图像大小一致
  1. 裁剪图像

在Pillow库的Image模块中,函数crop()功能是剪切图片中的box指定的区域

Image.crop(box=None)

参数box是一个四元组,分别定义了剪切区域的左、上、右、下4个坐标

from PIL import Image

img=Image.open('02.jpg')

#复制
imgb=img.copy()
imgc=img.copy()

#剪切
img_crop=imgb.crop((10,10,200,200))

imgc.paste(img_crop,(150,150))
imgc.show()

image.png

图像旋转

在pillow库中的Image模块中,函数rotate()功能返回此图像的副本,围绕其中心逆时针旋转给定的度数

Image.rotate(angle,raesample=0,expand=0,center=None,tanslate=None,fillcolor=None)

image.png

格式转换

  1. covert()

在Pillow库中的Image模块中,函数conver()返回模式转换后的图像实例
Image.covert(mode=None,matrix=None,dither=None,palette=0,colors=256)
其中mode:转换文件的模式,默认支持的模式有“L”、“RGB”、“CMYK”;matrix:
转使用的矩阵;dither:取值为None切转为黑白图时非0(1-255)像素均为白,也可以设置此参数为
FLOYDSTEINBERG

  1. transpse()

实现图像格式的转化

Image.transpose(method)
转换图像后,返回转换后的图像,“method”的取值有以下几个:

  1. PIL.Image.FLIP_LEFT_RIGHT:左右镜像
  2. PIL.Image.FLIP_TOP_BOTTOM:上下镜像
  3. PIL.Image.ROTATE_90:旋转90
  4. PIL.Image.ROTATE_180:旋转180
  5. PIL.Image.ROTATE_270:旋转270
  6. PIL.Image.TRANSPOSE:颠倒顺序

image.png

分离和合并

  1. 分离

使用split()可以将图片分割为多个通道列表
Image.split()

  1. 合并

使用函数merge()可以将一个通道的图像合并到更多的通道的图像中

Image.merge(mode,bands)

其中mode指定输出图像的模式,bands波段通道,一个序列单个带图通道

from PIL import Image

img1=Image.open('01.jpg')
img2=Image.open('02.jpg')
img2=img2.resize(img1.size)

r1,g1,b1=img1.split()
r2,g2,b2=img2.split()

temp=[r1,g2,b1]
img=Image.merge('RGB',temp)
img.show()

image.png

滤镜

在Pillow库中的Image模块中,使用函数filter()可以对指定的图片使用滤镜效果,在Pillow库中可以用的滤镜保存在ImageFilter模块中

Image.filter(filter)

from PIL import Image,ImageFilter

img=Image.open('02.jpg')

w,h=img.size

img_output=Image.new('RGB',(2*w,h))
img_output.paste(img,(0,0))
img.filter=img.filter(ImageFilter.GaussianBlur)
img_output.paste(img.filter,(w,0))
img_output.show()

image.png

其他内置模块

常用的属性

  1. Image.format:源图像格式
  2. Image.mode:图像模式字符串
  3. Image.size:图像尺寸

在Pillow库中的Image模块中,其他内置函数如下:

  1. Image.getbands():获取图像每个通道的 名称列表,例如RGB图像返回[‘R’,‘G’,‘B’]
  2. Image.getextrema():获取图像最大、最小像素的值
  3. Image.getpixel(xy):获取像素点值
  4. Image.histogram(mask=None,extrema=None):获取图像直方图,返回像素计数的列表
  5. Image.point(function):使用函数修改的每个像素
  6. Image.putaoha(alpha):添加或替换图像的alpha层
  7. Image.save(fp,formal=None,**params):保存图片
  8. Image.show(title=None,command=None):显示图片
  9. Image.transform(size,method,data=None,resample=0,fill=1):变换图像
  10. Image.verify():校验文件是否损坏
  11. Image.close():关闭文件

ImageFilter模块

BLUE:模糊
CONTOUR:轮廓
DETAIL:详情
EDGE_ENHANCE:边缘增强
EDGE_ENHANCE_MORE:边缘更多增强
EMBOSS:浮雕
FIND_EDGES:寻找边缘
SHARPEN:锐化
SMOOTH:平滑

函数名 功能
ImageFilter.GaussianBlur(radius=2) 高斯模糊
ImageFilter.UnsharpMask(radius=2,parcent=150,threshold=3) 不清晰的掩模滤镜
ImageFilter.MinFilter(size=3) 最小值滤波
ImageFilter.MedianFilter(size=3) 中值滤波
ImageFilter.ModeFilter(size=3) 模式滤波

ImageChops模块

pillow库中内置模块ImageChops中包含了用于实现图片合成的函数,这些合成的功能是通过计算通道中的像素值的方式来实现的,其主要用于制作特效、合成图片等操作

  1. 相加函数add(),功能是对两张图片进行加法运算

ImageChop.add(img1,img2,scale=1.0,offset=0)
在合成后图像中的每个像素值,是两幅图像对应像素值根据下面的公式计算得到的
out=((img1+img2)/scale+offset)

  1. 减法函数subtract()

ImageChop.subtract(img1,img2,scale=1.0,offset=0)
在合成后图像中的每个像素值,是两幅图像对应像素值根据下面的公式计算得到的
out=((img1-img2)/scale+offset)

  1. 变暗函数darker(),功能是比较两个图片的像素,取两张图片中对应的较小值,所以合成时两幅图像中对应位置的暗部分得到保留,而除去亮部分

ImageChops.darker(img1,img2)
计算公式如下:
out=min(img1,img2)

  1. 变亮函数与darker()相反,取亮的部分

ImageChops.lighter(img1,img2)
计算公式如下:
out=max(img1,img2)

  1. 叠加函数multiply(),功能是将两张图片互相叠加,如果用纯黑色与某图片进行叠加操作,就会得到一幅纯黑的图片。如果用纯白色图片叠加则不受影响

ImageChops.multiply(img1,im2)

计算公式如下:
out=image1*image2/MAX

  1. 屏幕函数screen(),功能是先反色后叠加,实现合成图像的效果。

ImageChops.screen(img1,img2)

计算公式如下
out=MAX-((MAX-image1)*(MAX-image2)/MAX)

  1. 反色函数invert(),类似于集合操作中求补集,最大值为Max,取出反色,在反色时将用255减去一幅图像的每个像素值,从而得到原来图像的反色,表现为“底片”的性质图像

ImageChops.invert(img)
计算公式如下:
out=MAX-img

  1. 比较函数difference(),可以逐像素做减法操作,计算出绝对值。difference()能够两幅图像的对应像素值相减后的图像,对应像素值相同的,则为黑色。

ImageChops.difference(img1,img2)

计算公式如下:
out=abs(img1-img2)

ImageEnhance模块

内置ImageEnhance模块包含多个用于增强图像效果的函数,主要用来调整图像的色彩、对比度、亮度和清晰度。

在ImageEnhance中,所有的图片增强对象都实现一个通用接口。这个接口只包含如下一个方法:

方法enhance()会返回一个增强Image对象,参数factor是一个大于0的浮点数,1表示返回原始图片

在Python中使用模块ImageEnhanced增强效果时,需要首先创建对应的增强调整器,然后调用调整器,根据指定的增强系数(小于1表示减弱,大于1表示增强,等于1表示原图不变)进行调整,最后输出调整后的图像

  1. ImageEnhanced.Color(image)功能是调整图像色彩平衡。
  2. ImageEnhanced.Brightness(images):功能时调整图像对比度
  3. ImageEnhancedSharpness(images):调整图像的清晰度,用于锐化/钝化图片

锐化操作的factor时0~2之间的一个浮点数,当factor=0时,返回一个模糊图片对象,当factor=2时,返回一个锐化的图片对象,当factor=1时,返回原始图片对象

from PIL import Image,ImageEnhance

img=Image.open('01.jpg')

w,h=img.size

img_output=Image.new('RGB',(3*w,h))

img_output.paste(img,(0,0))


#获取色彩调整器

img_color=ImageEnhance.Color(img)
imgb=img_color.enhance(1.5)
img_output.paste(imgb,(w,0))
imgc=img_color.enhance(0.3)
img_output.paste(imgc,(2*w,0))
img_output.show()

image.png

from PIL import Image,ImageEnhance

img=Image.open('01.jpg')

w,h=img.size

img_output=Image.new('RGB',(3*w,h))

img_output.paste(img,(0,0))


#获取亮度调整器

img_color=ImageEnhance.Brightness(img)
imgb=img_color.enhance(1.5)
img_output.paste(imgb,(w,0))
imgc=img_color.enhance(0.3)
img_output.paste(imgc,(2*w,0))
img_output.show()

image.png

from PIL import Image,ImageEnhance

img=Image.open('01.jpg')

w,h=img.size

img_output=Image.new('RGB',(3*w,h))

img_output.paste(img,(0,0))


imgb=img.point(lambda i:i*1.4)

imgc=img.point(lambda i:i*0.3)


img_output.paste(imgb,(w,0))
img_output.paste(imgc,(2*w,0))



img_output.show()

image.png

ImageDraw模块

实现绘图功能,可以在创建图片的方式,还可以在原有的图片上进行绘制

drawObject=ImageDraw.Draw(black)

  1. 绘制直线

drawObject.line([x1,y1,x2,y2],fill=None,width=0,joint=None)
表示以(x1,y1)为起始点,以(x2,y2)为终点画的一条直线,[x1,y1,x2,y2]也可写成(x1,y1,x2,y2)、[(x1,y1),(x2,y2)]等,fill用于设置指定线条颜色,width设置线条的宽度,joint表示一系列之间的联合类型,它可以称为“曲线”

  1. 绘制圆弧

drawObject.arc([x1,y1,x2,y2],start,end,fill=None,width=0)
在左上坐标(x1,y1),右下角坐标为(x2,y2)的矩形区域内,满员O内,以start为起始角度,以end为终止角度,截取园O的一部分圆弧并画出来。如果[x1,y1,x2,y2]区域不是正方形,则在该区域内的最大椭圆中根据角度截取片段
参数fill和width与line方法相同

  1. 绘制椭圆

drawObject.ellipse([x1,y1,x2,y2],fill=None,outline=None,width=0)
outline规定圆的颜色

  1. 绘制弦

drawObject.chord([x1,y1,x2,y2],start,end,fill=None,outline=None,width=0)
fill表示弦与圆弧之间空间指定颜色填满,设置outline表示只规定弦线的颜色

  1. 绘制扇形

drawObject.pieslice([x1,y1,x2,y2],start,end,fill=None,outline=None,width=0)

  1. 绘制矩形

drawObject.rectangle([x1,y1,x2,y2],start,end,fill=None,outline=None,width=0)

  1. 绘制文字

drawObject.text(position,text,fill=None,font=None,anchor=None,sapacing=0,align="left",direction=None,features=None,language=None)

  1. 绘制点

drawObject.point(xy,fill=None)



from PIL import Image,ImageDraw,ImageFont

img=Image.new('RGB',(300,200),'white')

draw_obj=ImageDraw.Draw(img)
draw_obj.rectangle((50,50,150,150),fill='blue',outline='red')
font=ImageFont.truetype('SIMLI.TTF',20)
draw_obj.text((100,100),'aaa',fill='white',font=font)
img.show()

image.png

from PIL import Image,ImageDraw

img=Image.open('01.jpg')

width,height=img.size

draw_obj=ImageDraw.Draw(img)

draw_obj.arc((0,0,width-1,height-1),0,360,fill='blue')
img.show()

image.png

ImageFont模块

对字体和字型做处理

  1. load(),从指定文件中加载一种字体,该函数返回对应的字体对象。如果函数运行失败,那么将产生IOerror异常

ImageFont.load(文件名)

  1. load_path():和load()一样,如果没有指定当前路径,就会从文件sys.path开始查找指定的字体文字

ImageFont.load_path(文件名)

  1. truetype()有两种定义格式,第1种格式功能是加载一个TrueType或者OpenType字体文件,并且创建一个字体对象

ImageFont.trueType(file,size)

第2种是加载一个TrueType或者OpenType字体文件,并创建一个字体对象。通常编码方式是“unic”(Unicode)、“symb”(MicroSoftSymbol)、“ADOB”(Adobe Standard)、“ADBE”(Adobe Expert)和“armn”(Apple Roman)
ImageFont.trueType(file,encoding=value)

  1. load_default(),加载一种默认的字体

ImageFont.load_default()

  1. getsize()返回给定文本的宽度和高度,返回值是一个二元组

ImageFont.getsize

from PIL import Image,ImageFont,ImageDraw

img=Image.open('01.jpg')

draw_obj=ImageDraw.Draw(img)

font=ImageFont.load_default()


font=ImageFont.truetype('SIMYOU.TTF',80)

draw_obj.text((30,30),'wefwdef',font=font,fill='black')
img.show()

image.png


from PIL import Image,ImageDraw

img=Image.open('01.jpg')

draw_obj=ImageDraw.Draw(img)

w,h=img.size

draw_obj.line((0,0,w,h),fill=(255,255,0),width=3)
draw_obj.line((0,h,w,0),fill=(255,255,0),width=3)
img.show()

image.png

from PIL import Image,ImageDraw,ImageFont
import random
width,height=100,100

img=Image.new('RGB',(width,height),(255,255,255))

#获取draw_obj对象
draw_obj=ImageDraw.Draw(img)

def get_color():
    return (random.randint(200,255),random.randint(200,255),random.randint(200,255))


for x in range(height):
    for y in range(height):
        draw_obj.point((x,y),fill=get_color())

def get_char():
    return chr( random.randint(65,97))

font=ImageFont.truetype('simsun.ttc',36)

for i in range(4):
    draw_obj.text((10+i*20,40),get_char(),font=font,fill=(255,0,0))


draw_obj.line((0,0,100,100),fill='green',width=5)


img.show()

image.png


from PIL import Image,ImageDraw

width,height=300,300

img=Image.new('RGB',(width,height),(255,255,255))

draw_obj=ImageDraw.Draw(img)

def get_color(x,y):
    a=x//100+y//100
    if a==0:
        return (255,0,0)
    elif a==1:
        return (255,255,0)
    elif a==2:
        return (255,255,255)

    elif a==3:
        return (0,0,255)
    elif a==4:
        return (0,255,255)
    else:
        return (0,0,0)

for x in range(width):
    for y in range(height):
        draw_obj.point((x,y),fill=get_color(x,y))

img.show()

image.png