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