python图片处理工具pillow

一,pillow的安装

pip install pillow 

二,pillow的基本概念

PIL中所涉及的基本概念有如下几个:
1)通道(bands)、2)模式(mode)、3)尺寸(size)、4)坐标系统(coordinate system)、5)调色板(palette)、6)信息(info)7)滤波器(filters)。

1、 通道

每张图片都是由一个或者多个数据通道构成。PIL允许在单张图片中合成相同维数和深度的多个通道。
以RGB图像为例,每张图片都是由三个数据通道构成,分别为R、G和B通道。而对于灰度图像,则只有一个通道。

对于一张图片的通道数量和名称,可以通过方法getbands()来获取。
方法getbands()是Image模块的方法,它会返回一个字符串元组(tuple)。该元组将包括每一个通道的名称。

例如:

from PIL import Image

img = Image.open("./file_space/image1.png")
print(img.getbands())

#---output--------------
# A代表透明度
('R', 'G', 'B', 'A')
2、 模式

图像的模式定义了图像的类型和像素的位宽。当前支持如下模式:

from PIL import Image
img = Image.open("./picture/image1.png")
print(img.mode)
3、 尺寸

通过size属性可以获取图片的尺寸。这是一个二元组,包含水平和垂直方向上的像素数。

from PIL import Image
img = Image.open("./picture/image1.png")
print(img.size)
4、 坐标系统

PIL使用笛卡尔像素坐标系统,坐标(0,0)位于左上角。注意:坐标值表示像素的角;位于坐标(0,0)处的像素的中心实际上位于(0.5,0.5)。

坐标经常用于二元组(x,y)。长方形则表示为四元组,前面是左上角坐标。例如,一个覆盖800x600的像素图像的长方形表示为(0,0,800,600)。

5、 调色板

调色板模式 (“P”)使用一个颜色调色板为每个像素定义具体的颜色值

6、 信息

使用info属性可以为一张图片添加一些辅助信息。这个是字典对象。加载和保存图像文件时,多少信息需要处理取决于文件格式。

from PIL import Image
img = Image.open("./picture/image1.png")
print(img.info)
7、 滤波器

对于将多个输入像素映射为一个输出像素的几何操作,PIL提供了4个不同的采样滤波器:

  • NEAREST:最近滤波。从输入图像中选取最近的像素作为输出像素。它忽略了所有其他的像素。
  • BILINEAR:双线性滤波。在输入图像的2x2矩阵上进行线性插值。注意:PIL的当前版本,做下采样时该滤波器使用了固定输入模板。
  • BICUBIC:双立方滤波。在输入图像的4x4矩阵上进行立方插值。注意:PIL的当前版本,做下采样时该滤波器使用了固定输入模板。
  • ANTIALIAS:平滑滤波。这是PIL 1.1.3版本中新的滤波器。对所有可以影响输出像素的输入像素进行高质量的重采样滤波,以计算输出像素值。在当前的PIL版本中,这个滤波器只用于改变尺寸和缩略图方法。
  • 注意:在当前的PIL版本中,ANTIALIAS滤波器是下采样(例如,将一个大的图像转换为小图)时唯一正确的滤波器。BILIEAR和BICUBIC滤波器使用固定的输入模板,用于固定比例的几何变换和上采样是最好的。
    Image模块中的方法resize()和thumbnail()用到了滤波器。

方法resize()的使用如下:

# 方法resize()的定义为:resize(size, filter=None)=> image
from PIL import Image
im = Image.open("xiao.png")
print(im.size)
im_resize = im.resize((256,256))
print(im_resize.size)

#---output--------------
(670, 502)
(256,256)

对参数filter不赋值的话,方法resize()默认使用NEAREST滤波器。如果要使用其他滤波器可以通过下面的方法来实现:

from PIL import Image
img = Image.open("./file_space/image1.png")
print(img.size)
img.show()

im_resize0 = img.resize((256,256), Image.NEAREST)
print(im_resize0.size)
im_resize0.show()
 
im_resize1 = img.resize((256,256), Image.BILINEAR)
print(im_resize1.size)
im_resize1.show()

im_resize2 = img.resize((256,256), Image.BICUBIC)
print(im_resize2.size)
im_resize2.show()

im_resize3 = img.resize((256,256), Image.ANTIALIAS)
print(im_resize3.size)
im_resize3.show()

#---output--------------
(400, 140)
(256, 256)
(256, 256)
(256, 256)
(256, 256)

三、Image模块:

Image模块是PIL中最重要的模块,它有一个类叫做image,与模块名称相同。Image类有很多函数、方法及属性,接下来将依次对image类的属性、函数和方法进行介绍。

1,Image类的属性
1) Format

定义:im.format ⇒ string or None
含义:源文件的文件格式。如果是由PIL创建的图像,则其文件格式为None。

例子:

from PIL import Image

img = Image.open("./picture/image1.png")
print(img.format)
img.show()

#---output--------------
'PNG'
2) Mode

图像的模式定义了图像的类型和像素的位宽。当前支持如下模式:

  • 1:1位像素,表示黑和白,但是存储的时候每个像素存储为8bit。
  • L:8位像素,表示黑和白。
  • P:8位像素,使用调色板映射到其他模式。
  • RGB:3x8位像素,为真彩色。
  • RGBA:4x8位像素,有透明通道的真彩色。
  • CMYK:4x8位像素,颜色分离。
  • YCbCr:3x8位像素,彩色视频格式。
  • I:32位整型像素。
  • F:32位浮点型像素。
  • PIL也支持一些特殊的模式,包括RGBX(有padding的真彩色)和RGBa(有自左乘alpha的真彩色)。

可以通过mode属性读取图像的模式。其返回值是包括上述模式的字符串。
属性mode的使用如下:

from PIL import Image
img = Image.open("./picture/image1.png")
print(img.mode)
img.show()

#---output--------------  
'RGBA'
3) Size

定义:im.size ⇒ (width, height)
含义:图像的尺寸,按照像素数计算。它的返回值为宽度和高度的二元组(width, height)。

属性mode的使用如下:

from PIL import Image
img = Image.open("./picture/image1.png")
print(img.size)     # 图片的尺寸
print(img.width)    #图片的宽
print(img.height)   #图片的高
print(img.format)   # 图片的格式print(img.size)
img.show()

#---output--------------
(606, 691)
606
691
PNG
4) Palette

定义:im.palette ⇒ palette or None
含义:颜色调色板表格。如果图像的模式是“P”,则返回ImagePalette类的实例;否则,将为None。

例子:

from PIL import Image

img = Image.open("./picture/image1.png")
print(img.mode)
print(img.palette)

#---output--------------
RGBA
None
5) Info

定义:im.info ⇒ dictionary
含义:存储图像相关数据的字典。文件句柄使用该字典传递从文件中读取的各种非图像信息。大多数方法在返回新的图像时都会忽略这个字典;因为字典中的键并非标准化的,对于一个方法,它不能知道自己的操作如何影响这个字典。
如果用户需要这些信息,需要在方法open()返回时保存这个字典。

属性info的使用如下:

from PIL import Image
img = Image.open("xiao.png")
print(img.info)

#---output--------------
{'srgb': 0, 'gamma': 0.45455, 'dpi': (96, 96)}
2、类的函数:
1)New

定义:Image.new(mode,size) ⇒ image
Image.new(mode, size, color) ⇒ image
含义:使用给定的变量mode和size生成新的图像。Size是给定的宽/高二元组,这是按照像素数来计算的。对于单通道图像,变量color只给定一个值;对于多通道图像,变量color给定一个元组(每个通道对应一个值)。
在版本1.1.4及其之后,用户也可以用颜色的名称,比如给变量color赋值为“red”。如果没有对变量color赋值,图像内容将会被全部赋值为0(图像即为黑色)。如果变量color是空,图像将不会被初始化,即图像的内容全为0。
这对向该图像复制或绘制某些内容是有用的。

例子:

from PIL import Image
img = Image.new("RGB", (128, 128), "#FF0000")
img.save("test1.png")   #图像im为128x128大小的红色图像。
img.show()

img = Image.new("RGB", (128, 128))   #图像im为128x128大小的黑色图像,因为变量color不赋值的话,图像内容被设置为0,即黑色。
img.save("test2.png")
img.show()

img= Image.new("RGB", (128, 128), "red")   #图像im为128x128大小的红色图像。
img.show()
img.save("test3.png")
2)Open

定义:Image.open(file) ⇒ image
Image.open(file, mode) ⇒ image
含义:打开并确认给定的图像文件。这个是一个懒操作;该函数只会读文件头,而真实的图像数据直到试图处理该数据才会从文件读取(调用load()方法将强行加载图像数据)。如果变量mode被设置,那必须是“r”。
用户可以使用一个字符串(表示文件名称的字符串)或者文件对象作为变量file的值。文件对象必须实现read(),seek()和tell()方法,并且以二进制模式打开。

例子:
from PIL import Image
img = Image.open("./picture/image1.png")
img.show()
3)Blend

定义:Image.blend(image1,image2, alpha) ⇒ image
含义:使用给定的两张图像及透明度变量alpha,插值出一张新的图像。这两张图像必须有一样的尺寸和模式。
合成公式为:out = image1 *(1.0 - alpha) + image2 * alpha
如果变量alpha为0.0,将返回第一张图像的拷贝。如果变量alpha为1.0,将返回第二张图像的拷贝。对变量alpha的值没有限制。

例子:

from PIL import Image
img1 = Image.open("./file_space/image1.png")
img2 = Image.open("./file_space/image2.png")

img1 = img1.resize((300,300), Image.ANTIALIAS)
img2 = img2.resize((300,300), Image.ANTIALIAS)

im = Image.blend(img1,img2,0.5)
im.show()
im.save("he.png")
4) Composite

定义:Image.composite(image1,image2, mask) ⇒ image
含义:使用给定的两张图像及mask图像作为透明度,插值出一张新的图像。变量mask图像的模式可以为“1”,“L”或者“RGBA”。所有图像必须有相同的尺寸。
例子:

from PIL import Image
im1 = Image.open("jing.jpg")
im2 = Image.open("wu.jpg")
r,g,b = im1.split()
print(g.mode)
im = Image.composite(im1,im2,b)
im.save("he.jpg")
b.save("he1.jpg")
5)Eval

定义:Image.eval(image,function) ⇒ image
含义:使用变量function对应的函数(该函数应该有一个参数)处理变量image所代表图像中的每一个像素点。如果变量image所代表图像有多个通道,那变量function对应的函数作用于每一个通道。
注意:变量function对每个像素只处理一次,所以不能使用随机组件和其他生成器。
例子:

from PIL import Image
img = Image.open("./picture/image1.png")
img.show()

def deffun(c):
    return c*0.5     #改变了亮度

im_eval = Image.eval(img,deffun) 
im_eval.show()
im_eval.save("gai.jpg")

注:图像im_eval与im01比较,其像素值均为im01的一半,则其亮度自然也会比im01暗一些。

6)Merge

定义:Image.merge(mode,bands) ⇒ image
含义:使用一些单通道图像,创建一个新的图像。变量bands为一个图像的元组或者列表,每个通道的模式由变量mode描述。所有通道必须有相同的尺寸。
变量mode与变量bands的关系:
len(ImageMode.getmode(mode).bands)= len(bands)
例子:

from PIL import Image
img1 = Image.open("./picture/image1.png")
img2 = Image.open("./picture/image3.png")
img1 = img1.resize((300,300), Image.ANTIALIAS)
img2 = img2.resize((300,300), Image.ANTIALIAS)
r1,g1,b1,a1 = img1.split()
r2,g2,b2,a1 = img2.split()
imgs =[r1,g2,b2]
im_merge = Image.merge("RGB",imgs)
im_merge.show()
im_merge.save("he.jpg")
3,Image类的方法

除非另作说明,Image类的所有方法都将返回一个Image类的新实例,这个实例对应于结果图像。

1)Convert

im.convert(mode)⇒ image

将当前图像转换为其他模式,并且返回新的图像。当从一个调色板图像转换时,这个方法通过这个调色板来转换像素。如果不对变量mode赋值,该方法将会选择一种模式,在没有调色板的情况下,使得图像和调色板中的所有信息都可以被表示出来。当从一个颜色图像转换为黑白图像时,PIL库使用ITU-R601-2 luma转换公式:

L = R * 299/1000 + G * 587/1000 + B * 114/1000

当转换为2位图像(模式“1”)时,源图像首先被转换为黑白图像。结果数据中大于127的值被设置为白色,其他的设置为黑色;这样图像会出现抖动。如果要使用其他阈值,更改阈值127,可以使用方法point()。为了去掉图像抖动现象,可以使用dither选项。。
 
例子1:

from PIL import Image
img = Image.open("./picture/image1.png")
print(img.mode)
im.show()
new_img = img.convert('P')
print(new_img.mode)
new_img.show()
# --------------------------------------
RGBA
P

im.convert(“P”,**options) ⇒ image

这个与第一个方法定义一样,但是当“RGB”图像转换为8位调色板图像时能更好的处理。可供选择的选项为:

Dither=. 控制颜色抖动。默认是FLOYDSTEINBERG,与邻近的像素一起承担错误。不使能该功能,则赋值为NONE。

Palette=. 控制调色板的产生。默认是WEB,这是标准的216色的“web palette”。要使用优化的调色板,则赋值为ADAPTIVE。

Colors=. 当选项palette为ADAPTIVE时,控制用于调色板的颜色数目。默认是最大值,即256种颜色

im.convert(mode,matrix) ⇒ image

使用转换矩阵将一个“RGB”图像转换为“L”或者“RGB”图像.

from PIL import Image
im = Image.open("./picture/image1.png")
print(im.mode)
new_im = im.convert("L")
print(new_im.mode)
new_im.show()
#----------------------------------
RGBA
L
2)Copy

定义:im.copy() ⇒ image
含义:拷贝这个图像。如果用户想粘贴一些数据到这张图,可以使用这个方法,但是原始图像不会受到影响。

例子:

from PIL import Image
im1 = Image.open("jing.jpg")
im2 = im1.copy()
im2.save("he.jpg")

注:图像im_copy和im01完全一样。

3)Crop

定义:im.crop(box) ⇒ image
含义:从当前的图像中返回一个矩形区域的拷贝。变量box是一个四元组,定义了左、上、右和下的像素坐标。
这是一个懒操作。对源图像的改变可能或者可能不体现在裁减下来的图像中。为了获取一个分离的拷贝,对裁剪的拷贝调用方法load()。

例子:

from PIL import Image
im1 = Image.open("./picture/image1.png")
print(im1.size)
box = [0,0,350,1344]   #350(长)1344(高)
im_crop = im1.crop(box)
im1.show()
im_crop.show()
4)Draft

定义:im.draft(mode,size)
含义:配置图像文件加载器,使得返回一个与给定的模式和尺寸尽可能匹配的图像的版本。例如,用户可以使用这个方法,在加载一个彩色JPEG图像时将其转换为灰色图像,或者从一个PCD文件中提取一个128x192的版本。
注意:这个方法会适时地修改图像对象(精确地说,它会重新配置文件的读取器)。如果图像已经被加载,那这个方法就没有作用了。

例子:

from PIL import Image
im1 = Image.open("jing.jpg")
im_draft = im1.draft("L",(500,500))
print(im_draft.size)
im_draft.save("he.jpg")
输出:
(650, 650)
5)Filter

定义:im.filter(filter) ⇒ image
含义:返回一个使用给定滤波器处理过的图像的拷贝。可用滤波器需要参考ImageFilter模块。

例子:

from PIL import Image 
from PIL import ImageFilter ## 调取ImageFilter 
imgF = Image.open("./picture/image2.jpg") 
bluF = imgF.filter(ImageFilter.BLUR) ##均值滤波 
conF = imgF.filter(ImageFilter.CONTOUR) ##找轮廓 
edgeF = imgF.filter(ImageFilter.FIND_EDGES) ##边缘检测 
imgF.show() 
bluF.show() 
conF.show() 
edgeF.show()

注:图像im_filter比im01变得有些模糊了。

6)Fromstring

定义:im.fromstring(data)
im.fromstring(data, decoder,parameters)
含义:与函数fromstring()一样,但是这个方法会将data加载到当前的图像中。

7)Getbands

定义:im.getbands()⇒ tuple of strings
含义:返回包括每个通道名称的元组。例如,对于RGB图像将返回(“R”,“G”,“B”)。

from PIL import Image 

img = Image.open("./picture/image1.png")
img.getbands()
#----output----------------------------
('R', 'G', 'B', 'A')
8)Getbbox

定义:im.getbbox() ⇒ 4-tuple or None
含义:计算图像非零区域的包围盒。这个包围盒是一个4元组,定义了左、上、右和下像素坐标。如果图像是空的,这个方法将返回空。

例子:

from PIL import Image
img = Image.open("./picture/image1.png")
print(img.getbbox())
#--output-------------------------------
(0, 0, 750, 1344)
9)Getcolors

定义:im.getcolors() ⇒ a list of(count, color) tuples or None
im.getcolors(maxcolors) ⇒ a list of (count, color) tuples or None
含义:(New in 1.1.5)返回一个(count,color)元组的无序list,其中count是对应颜色在图像中出现的次数。
如果变量maxcolors的值被超过,该方法将停止计算并返回空。变量maxcolors默认值为256。为了保证用户可以获取图像中的所有颜色,you can pass in size[0]*size[1](请确保有足够的内存做这件事)。

例子:

from PIL import Image
img = Image.open("./picture/image1.png")
temp_list = img.getcolors(88888888)
max(temp_list)
#---output------------------------------------
(370308, (245, 246, 250, 255))
10)Getdata

定义:im.getdata() ⇒ sequence
含义:以包含像素值的sequence对象形式返回图像的内容。这个sequence对象是扁平的,以便第一行的值直接跟在第零行的值后面,等等。
注意:这个方法返回的sequence对象是PIL内部数据类型,它只支持某些sequence操作,包括迭代和基础sequence访问。使用list(im.getdata()),将它转换为普通的sequence。

例子:

from PIL import Image
from PIL import Image
im1 = Image.open("./picture/image1.png")
seq = im1.getdata()
print(seq[0],type(seq))
seq0 = list(seq)
print(seq0[0])
print(len(seq0))
#---output------------------------------------
(245, 246, 250, 255) <class 'ImagingCore'>
(245, 246, 250, 255)
1008000

注:Sequence对象的每一个元素对应一个像素点的R、G和B三个值。

11)Getextrema

定义:im.getextrema() ⇒ 2-tuple
含义:返回一个2元组,包括该图像中的最小和最大值。

例子:

from PIL import Image
img = Image.open("./picture/image1.png")
print(img.getextrema())
#---output------------------------------------
((0, 255), (0, 255), (0, 255), (255, 255))
该方法返回了R/G/B三个通道的最小和最大值的2元组。
12)Getpixel

定义:im.getpixel(xy) ⇒ value or tuple
含义:返回给定位置的像素值。如果图像为多通道,则返回一个元组。
注意:该方法执行比较慢;如果用户需要使用python处理图像中较大部分数据,可以使用像素访问对象(见load),或者方法getdata()。

例子:

from PIL import Image
im1 = Image.open("./picture/image1.png")
print(im1.getpixel((1,1)))
print(im1.getpixel((649,649)))
#-------------------------------------------
(41, 183, 197)
(236, 210, 153)

注:im.getpixel(xy)中的X,Y表示坐标,从0开始。

13)Histogram

定义1:im.histogram()⇒ list
含义1:返回一个图像的直方图。这个直方图是关于像素数量的list,图像中的每个象素值对应一个成员。如果图像有多个通道,所有通道的直方图会连接起来(例如,“RGB”图像的直方图有768个值)。
二值图像(模式为“1”)当作灰度图像(模式为“L”)处理。

例子1:

from PIL import Image
im1 = Image.open("jing.jpg")
ls = im1.histogram()
print(len(ls))
print(ls[767])
输出:
768
1471
14) Load

定义:im.load()
含义:为图像分配内存并从文件中加载它(或者从源图像,对于懒操作)。正常情况下,用户不需要调用这个方法,因为在第一次访问图像时,Image类会自动地加载打开的图像。

 (New in 1.1.6)在1.1.6及以后的版本,方法load()返回一个用于读取和修改像素的像素访问对象。这个访问对象像一个二维队列,如:
  pix = im.load()
  print pix[x, y]
  pix[x, y] =value
  通过这个对象访问比方法getpixel()和putpixel()快很多。

例子:

from PIL import Image
im1 = Image.open("jing.jpg")
lm_load = im1.load()
print(lm_load[649,649])
输出:
(236, 210, 153)
15)Paste

im.paste(image,box)

将一张图粘贴到另一张图像上。变量box或者是一个给定左上角的2元组,或者是定义了左,上,右和下像素坐标的4元组,或者为空(与(0,0)一样)。如果给定4元组,被粘贴的图像的尺寸必须与区域尺寸一样。如果模式不匹配,被粘贴的图像将被转换为当前图像的模式。

from PIL import Image
im = Image.open("./picture/image1.png")
box=[0,0,100,100]
im_crop = im.crop(box)
print(im_crop.size,im_crop.mode)
im.paste(im_crop, (100,100))             ##(100,100,0,0)
im.paste(im_crop, (400,400,500,500))
im.show()

猜你喜欢

转载自blog.csdn.net/TFATS/article/details/106624669