Python图像处理(Pillow/PIL)入门
来源:互联网 发布:手机淘宝店铺实名认证 编辑:程序博客网 时间:2024/06/04 17:49
Pillow概况
PIL是Python的一种图像处理工具。
PIL支持大部分的图像格式,高效并强大。
核心库设计用来高速访问基于基于像素的数据存储,给这个通用的图像处理工具提供了坚实的基础。
来看下这个库的一般用途:
图像归档
PIL是较为理想的图片归档和批处理应用。你可以使用这个库去生成缩略图、转换图片格式、打印图像等。
当前版本可以识别和读取大量的格式。写操作被限制用于大多数通用的转换处理和显示格式上。
图像展示
当前发行版本包含TkPhotoImage
和BitmapImage
接口,这个和Windows DIB interface
一样,可以用于PythonWin
和其他基于窗口的程序。许多其他的GUI程序都是基于PIL。
为了调试方便,PIL提供了show()
,用来保存图片到硬盘和调用外部图片查看器。
图形处理
PIL包含基本的图像处理功能,包括像素操作、一套内置卷积核的滤镜、色空间转换。
PIL支持图像缩放、旋转、任意角度的转换。
PIL支持用于统计图像的直方图。这个可以用来自动自动对比增强、全局统计分析。
安装
使用PIP安装
pip install Pillow
使用
使用Image类
Image类是PIL最核心的类,定义在同名的模块中。你可以创建这个类实例,可以通过加载图片文件、处理其他Image实例、或新建一个空的Image实例。
为了从图片文件加载Image类,需要使用Image
模块中的open()
方法。
>>> from PIL import Image>>> im = Image.open("hopper.ppm")
如果加载成功,这个函数会返回一个Image对象。你可以使用实例属性去查看文件内容。
>>> from __future__ import print_function>>> print(im.format, im.size, im.mode)PPM (512, 512) RGB
format
属性定义了图片来源格式。如果实例没有读取文件,format
就是None
。size属性是一个两个元素的元组,包含像素计的宽高。mode属性定义了图像通道的编号和名字,以及像素类型和深度。常用模式有用于灰度图的”L”(luminance)、用于真彩图的”RGB”、用于预印刷图的”CMYK”模式。
如果你没有打开文件,会触发一个IOError
异常。
一旦你有了一个Image
实例,你就可以使用类里的方法来处理和维护图像了。例如,让我们显示图像,我们仅仅加载如下:
>>> im.show()
这个版本的
show()
不是非常高效,因为他是保存图像到一个临时文件,然后调用xv协助去显示图像。如果你没有安装xv,他将不会工作。尽管他工作了,也会非常难以调试和测试。
下一节介绍PIL提供的几种不用的方法。
读写图像
PIL支持广泛的图片格式。为了从硬盘读取文件,需要使用Image
模块中的open()
方法。你不必知道文件格式就可以打开文件。PIL会根据文件内容自动判断文件格式。
可以使用Image
模块里的save()
方法来保存文件。保存文件的时候,命名会很重要。除非你规定了格式,PIL会用文件扩展名来存储。
转换图片为JPEG格式
from __future__ import print_functionimport os, sysfrom PIL import Imagefor infile in sys.argv[1:]: f, e = os.path.splitext(infile) outfile = f + ".jpg" if infile != outfile: try: Image.open(infile).save(outfile) except IOError: print("cannot convert", infile)
第二个参数被应用到save()
方法里,准确定义一个文件格式。如果你使用了一个非标准的扩展,你必须通过这种方式来定义格式:
创建JPEG缩略图
from __future__ import print_functionimport os, sysfrom PIL import Imagesize = (128, 128)for infile in sys.argv[1:]: outfile = os.path.splitext(infile)[0] + ".thumbnail" if infile != outfile: try: im = Image.open(infile) im.thumbnail(size) im.save(outfile, "JPEG") except IOError: print("cannot create thumbnail for", infile)
PIL不解码加载光栅数据,除非必须这样。当你打开一个文件,在文件头里就可以判断出文件格式,并抽取出像模式、大小和其他需要解码文件的属性,但是文件的其他部分不会被处理,除非以后需要。
这个意思就是打开图像文件是一个很快速的操作,这个跟文件大小和压缩方式无关。这里举几个简单的例子,快速识别一批图像文件。
识别图像文件
from __future__ import print_functionimport sysfrom PIL import Imagefor infile in sys.argv[1:]: try: with Image.open(infile) as im: print(infile, im.format, "%dx%d" % im.size, im.mode) except IOError: pass
剪切粘贴和合并图像
Image
类包含维护图像里区块的方法。为了从图像里抽取一个子矩形,使用crop()
方法。
复制一个子矩形
box = (100, 100, 400, 400)region = im.crop(box)
使用包含4个元素的元组来定义区块,相匹配的坐标是(左上右下)。PIL使用一个坐标系统,原点位于左上角。坐标系统使用像素来引用位置,所以上例中的区块大小是300x300像素。
现在这个区块可以以某种方式处理和粘贴了。
处理子矩形并粘贴
region = region.transpose(Image.ROTATE_180)im.paste(region, box)
当粘贴回的时候,区块大小必须精确匹配已给的区块大小。另外,这个区块不能扩展到外部图像。但是,原始图像的模式必须和区块的模式匹配。如果他们比匹配,区块会提前动转换为匹配的模式。
附件例子:
旋转图像
def roll(image, delta): "Roll an image sideways" xsize, ysize = image.size delta = delta % xsize if delta == 0: return image part1 = image.crop((0, 0, delta, ysize)) part2 = image.crop((delta, 0, xsize, ysize)) part1.load() part2.load() image.paste(part2, (0, 0, xsize-delta, ysize)) image.paste(part1, (xsize-delta, 0, xsize, ysize)) return image
当从crop()
粘贴回的时候,要先调用load()
。这是因为剪切是一个惰性操作。如果load()
没有被调用,剪切操作就不会执行,直到有粘贴命令执行。这就意味着part1
会被首先修改的image
剪切。
对于更高级的技巧,粘贴命令可以将透明遮罩作为可选参数。在这个遮罩里面,255表明在这个位置上粘贴的图像是不透明的。0表明粘贴的图像是完全透明的。在这两个值之间的数值表明不同级别的透明度。例如,粘贴一张RGBA图像,并使用它作为遮罩,将会粘贴图像不透明的部分,而不是他的透明背景。
PIL也可以让你处理单个或多个通道图像,例如RGB图像。split
方法创建了一套新的图像,每一个包含一个来源于原始多通道图像里的单个通道。merge
方法采用一种模式和一组图像,然后合并他们魏一张新图像。下面的样本代码交换了RGB图像的三种通道。
分割合并通道
r, g, b = im.split()im = Image.merge("RGB", (b, g, r))
对于单通道图像 ,split()
会返回图像本身。为作用于单色通道,你可以先转换图像为”RGB”模式。
几何变换
PIL.Image.Image
类包含一些变形和旋转图像方法resize()
、rotate()
。前者以一个元组为新尺寸,后者以逆时针的角度为角度。
简单的几何变换
out = im.resize((128, 128))out = im.rotate(45) # degrees counter-clockwise
旋转图像90度的步骤里,你可以使用rotate()
方法或transpose()
方法。后者还可以用于垂直或水平反转图像。
转换图像
out = im.transpose(Image.FLIP_LEFT_RIGHT)out = im.transpose(Image.FLIP_TOP_BOTTOM)out = im.transpose(Image.ROTATE_90)out = im.transpose(Image.ROTATE_180)out = im.transpose(Image.ROTATE_270)
transpose(ROTATE)
也可以执行相同于rotate()
的功能,如果expand
标签为真,则图像尺寸有相同的更改。
更详细的图像转换,可以查阅transform()
方法说明。
颜色转换
PIL可以使用convert()
方法在不同的像素表示之间转换。
转换图像模式
im = Image.open("hopper.ppm").convert("L")
该库支持每个受支持的模式、“L”和“RGB”模式之间的转换。
要在其他模式之间转换,您可能需要使用中间图像(通常是“RGB”图像)。
图象增强
PIL提供了许多方法和模块,可用于增强图像。
滤镜
ImageFilter
模块包含一些预定义的增强滤镜,可以与filter()
方法一起使用。
应用滤镜
from PIL import ImageFilterout = im.filter(ImageFilter.DETAIL)
点运算
point()
方法可以用来转换图像的像素值(例如图像对比操作)。在大多数情况下,期望一个参数的函数对象可以传递给这个方法。根据这个函数处理每个像素:
应用点转换
# multiply each pixel by 1.2out = im.point(lambda i: i * 1.2)
使用上面的技术,您可以快速地将任何简单的表达式应用于图像。您还可以组合point()
和paste()
方法来选择性地修改图像:
处理单通道
# split the image into individual bandssource = im.split()R, G, B = 0, 1, 2# select regions where red is less than 100mask = source[R].point(lambda i: i < 100 and 255)# process the green bandout = source[G].point(lambda i: i * 0.7)# paste the processed band back, but only where red was < 100source[G].paste(out, None, mask)# build a new multiband imageim = Image.merge(im.mode, source)
注意用于创建掩码的语法:
imout = im.point(lambda i: expression and 255)
Python只对逻辑表达式的部分进行评估,以确定结果,并返回所检查的最后一个值作为表达式的结果。因此,如果上面的表达式是假(0),那么Python不会查看第二个操作数,从而返回0。否则,它将返回255。
增强
对于更高级的图像增强,您可以使用ImageEnhance
模块中的类。一旦从图像中创建了,就可以使用增强对象快速尝试不同的设置。
你可以通过这种方式调整对比度、亮度、色彩平衡和清晰度。
增强图像
from PIL import ImageEnhanceenh = ImageEnhance.Contrast(im)enh.enhance(1.3).show("30% more contrast")
图像序列
PIL包含一些对图像序列的基本支持(也可以叫做动画格式)。支持的序列格式包括FLI/FLC、GIF和几个实验格式。TIFF文件还可以包含多个帧。
当您打开一个序列文件时,它会自动加载序列中的第一个帧。您可以使用seek和tell方法在不同的帧之间移动:
读取学列
from PIL import Imageim = Image.open("animation.gif")im.seek(1) # skip to the second frametry: while 1: im.seek(im.tell()+1) # do something to imexcept EOFError: pass # end of sequence
如本例中所示,当序列结束时,您将得到一个EOFError异常。
注意,当前版本库中的大多数驱动程序只允许您寻找下一帧(如上面示例中所示)。要重新修改文件,您可能需要重新打开它。
下面的类让您使用for语句来对序列进行循环:
使用ImageSequence迭代器类
from PIL import ImageSequencefor frame in ImageSequence.Iterator(im): # ...do something to frame...
Postscript打印
PIL包括打印图像、文字和在Postscript打印机上绘图的功能。这是一个简单的例子:
画Postscript
from PIL import Imagefrom PIL import PSDrawim = Image.open("hopper.ppm")title = "hopper"box = (1*72, 2*72, 7*72, 10*72) # in pointsps = PSDraw.PSDraw() # default is sys.stdoutps.begin_document(title)# draw the image (75 dpi)ps.image(box, im, 75)ps.rectangle(box)# draw titleps.setfont("HelveticaNarrow-Bold", 36)ps.text((3*72, 4*72), title)ps.end_document()
更多关于读取图像
如前所述,Image
模块的open()
函数用于打开图像文件。在大多数情况下,您只需将文件名作为参数传过去:
im = Image.open("hopper.ppm")
如果一切顺利,结果就是一个PIL.Image.Image
对象。否则,将抛出IOError异常。
您可以使用类似文件的对象而不是文件名。对象必须实现read()
、seek()
和tell()
方法,并以二进制模式打开。
从一个打开的文件读取
fp = open("hopper.ppm", "rb")im = Image.open(fp)
要从字符串数据中读取图像,使用StringIO
类:
从字符串读取
import StringIOim = Image.open(StringIO.StringIO(buffer))
请注意,在读取图像头之前,库会重新调整文件(使用seek(0)
)。此外,还可以在读取图像数据时使用seek(通过load方法)。
如果图像文件嵌入到较大的文件中,如tar文件,则可以使用ContainerIO
或TarIO
模块来访问它。
从tar压缩包里读取
from PIL import Image, TarIOfp = TarIO.TarIO("Tests/images/hopper.tar", "hopper.jpg")im = Image.open(fp)
控制解码器
一些解码器允许您在从文件中读取图像时对图像进行操作。在创建缩略图(通常速度比质量更重要)和打印到一个单色激光打印机(当需要只需要一个灰度版本的图像时),这通常可以用于加速解码。
draft()
方法操作一个已打开但尚未加载的图像,以便尽可能地匹配给定的模式和大小。这是通过重新配置图像解码器来完成的。
以草稿模式读取
这只适用于JPEG和MPO文件。
from PIL import Imagefrom __future__ import print_functionim = Image.open(file)print("original =", im.mode, im.size)im.draft("L", (100, 100))print("draft =", im.mode, im.size)
这个打印之类的:
original = RGB (512, 512)draft = L (128, 128)
注意,生成的图像可能与请求的模式和大小不完全匹配。为了确保图像不大于给定的大小,可以使用缩略图方法。
举例
微信验证码地址
https://mp.weixin.qq.com/mp/verifycode?cert=1494918122899.514
im=Image.open('dog.jpg') draw=ImageDraw.Draw(im) newfont=ImageFont.truetype('simkai.ttf',40) #设置字体,simkai为楷体,字体大小40,truetype相关知识可百度 draw.text((200,100),'you are so good!',(255,255,0),font=newfont) #第一个tuple表示要写在哪里,(left,up),之后写的#文字,颜色为黄色,三通道设置可以百度,第<span style="white-space:pre"> </span> #一个是红色,第二个绿色,第三个是蓝色,从0到255,最后设置字体 im.show()im.save('target.jpg')
参考
译文
- Python图像处理(Pillow/PIL)入门
- [Python] 图像简单处理(PIL or Pillow)
- pillow pil 图像处理
- python PIL/Pillow图像扩展、复制、粘贴处理
- python PIL/Pillow图像扩展、复制、粘贴处理
- Python 之 使用 PIL 库做图像处理(pillow+ImageDraw)
- python图像处理库Pillow入门(一)
- Python图像处理库Pillow入门
- 【python 图像处理】Python 图像处理库 Pillow 入门
- Python pillow Image图像处理
- python PIL PILLOW
- fedora python pillow pil
- Python学习之使用Pillow(PIL)进行图像操作方法详解
- python 进行图像处理(PIL)
- python PIL 图像处理 (二)
- PIL---使用Python处理图像
- Python图像处理库 PIL
- Python图像处理PIL模块
- 设计模式—策略模式(二)
- js判断上传文件大小 (尝试网上解决方案后结果....)
- 查入一个数,并排序
- Fragment-二
- 多维数组的例子-----> 杨辉三角
- Python图像处理(Pillow/PIL)入门
- 专业工具软件PCB板打印说明
- npm与cnpm
- 算法谜题65 猜密码
- java 方法重载
- javax.el.PropertyNotFoundException: Property 'fullName' not found on type java.lang.String
- PHP 抽奖demo
- [TensorFlow 学习笔记-02]配置PyCharm IDE环境
- 嵌入式系统学习——STM32之串口通信UART