使用Image类
Python Imaging Library中最重要的类是 :py:class:`~PIL.Image.Image`类,在模块中定义,具有相同的名称。您可以通过多种方式创建此类的实例; 通过从文件加载图像,处理其他图像或从头开始创建图像。
要从文件加载图像,请在:py:mod:`~PIL.Image`模块中使用:py:func:`~PIL.Image.open`函数:
>>>来自PIL导入图片
>>> im = Image.open(“hopper.ppm”)
如果成功,则此函数返回:py:class:`~PIL.Image.Image`对象。您现在可以使用实例属性来检查文件内容:
>>>来自__future__ import print_function
>>> print(im.format,im.size,im.mode)
PPM(512,512)RGB
的:吡啶:ATTR:`〜PIL.Image.Image.format`属性标识的图像的源。如果未从文件中读取图像,则将其设置为“无”。size属性是一个包含宽度和高度(以像素为单位)的2元组。的 :吡啶:ATTR:`〜PIL.Image.Image.mode`属性定义的数量和图像中的频带的名字,并且还像素类型和深度。常见模式是灰度图像的“L”(亮度),真彩色图像的“RGB”和印前图像的“CMYK”。
如果无法打开文件,则会引发:py:exc:`IOError`异常。
获得:py:class:`~PIL.Image.Image`类的实例后,可以使用此类定义的方法来处理和操作图像。例如,让我们显示刚刚加载的图像:
>>> im.show()
注意
标准版:py:meth:`~PIL.Image.Image.show`效率不高,因为它将图像保存到临时文件并调用 :command:`xv`实用程序来显示图像。如果您没有:command:`xv` 安装,它甚至不起作用。当它工作时,它非常方便调试和测试。
以下部分概述了此库中提供的不同功能。
读写图像
Python Imaging Library支持各种图像文件格式。要从磁盘读取文件,请在:py:mod:`~PIL.Image`模块中使用:py:func:`~PIL.Image.open`函数 。您无需知道打开文件的文件格式。库根据文件内容自动确定格式。
要保存文件,请使用:py:class:`~PIL.Image.Image`类的:py:meth:`~PIL.Image.Image.save`方法 。保存文件时,名称变得很重要。除非指定格式,否则库使用文件扩展名来发现要使用的文件存储格式。
将文件转换为JPEG
来自__future__ import print_function
import os,sys
来自PIL导入图片
对于infile in sys.argv [1:]:
f,e = os.path.splitext(infile)
outfile = f +“.jpg”
如果infile!= outfile:
尝试:
Image.open(INFILE).save(OUTFILE)
除了IOError:
打印(“无法转换”,infile)
第二个参数可以提供给:py:meth:`~PIL.Image.Image.save` 方法,该方法明确指定文件格式。如果使用非标准扩展,则必须始终以这种方式指定格式:
创建JPEG缩略图
来自__future__ import print_function
import os,sys
来自PIL导入图片
size =(128,128)
对于infile in sys.argv [1:]:
outfile = os.path.splitext(infile)[0] +“。thumbnail”
如果infile!= outfile:
尝试:
im = Image.open(infile)
im.thumbnail(大小)
im.save(outfile,“JPEG”)
除了IOError:
打印(“无法创建缩略图”,infile)
重要的是要注意,除非确实需要,否则库不会解码或加载栅格数据。当您打开文件时,将读取文件头以确定文件格式并提取解码文件所需的模式,大小和其他属性等内容,但文件的其余部分直到稍后才会处理。
这意味着打开图像文件是一种快速操作,它与文件大小和压缩类型无关。这是一个快速识别一组图像文件的简单脚本:
识别图像文件
来自__future__ import print_function
导入系统
来自PIL导入图片
对于infile in sys.argv [1:]:
尝试:
使用Image.open(infile)作为im:
print(infile,im.format,“%dx%d”%im.size,im.mode)
除了IOError:
通过
剪切,粘贴和合并图像
的:潘岳:类:`〜PIL.Image.Image`类包含让您在图像内操作区域的方法。要从图像中提取子矩形,请使用:py:meth:`~PIL.Image.Image.crop`方法。
从图像复制子矩形
box =(100,100,400,400)
region = im.crop(方框)
该区域由4元组定义,其中坐标为(左,上,右,下)。Python Imaging Library使用左上角带有(0,0)的坐标系。另请注意,坐标是指像素之间的位置,因此上例中的区域恰好是300x300像素。
现在可以以某种方式处理该区域并粘贴回来。
处理子矩形并将其粘贴回来
region = region.transpose(Image.ROTATE_180)
im.paste(地区,盒子)
将区域粘贴回来时,区域的大小必须与给定区域完全匹配。此外,该区域不能延伸到图像之外。但是,原始图像和区域的模式不需要匹配。如果没有,则在粘贴之前自动转换该区域( 有关详细信息,请参阅下面的参考:ref:`color-transforms`部分)。
这是另一个例子:
滚动图像
def roll(图像,delta):
“”将图像侧身翻滚。“”
xsize,ysize = image.size
delta = delta%xsize
如果delta == 0:返回图像
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))
返回图片
注意,当从:py:meth:`~PIL.Image.Image.crop` 操作粘贴它时,首先调用:py:meth:`~PIL.Image.Image.load`。这是因为裁剪是一种懒惰的操作。如果:py:meth:`~PIL.Image.Image.load`未被调用,则在粘贴命令中使用图像之前不会执行裁剪操作。这意味着part1
将从image
第一个粘贴已修改的版本中裁剪掉。
对于更高级的技巧,粘贴方法也可以将透明蒙版作为可选参数。在此掩码中,值255表示粘贴的图像在该位置是不透明的(也就是说,粘贴的图像应该按原样使用)。值0表示粘贴的图像完全透明。介于两者之间的值表示不同的透明度。例如,粘贴RGBA图像并将其用作蒙版将粘贴图像的不透明部分,但不粘贴其透明背景。
Python Imaging Library还允许您处理多波段图像的各个波段,例如RGB图像。分割方法创建一组新图像,每个图像包含来自原始多波段图像的一个波段。合并功能采用图像的模式和元组,并将它们组合成新图像。以下示例交换RGB图像的三个波段:
拆分和合并乐队
r,g,b = im.split()
im = Image.merge(“RGB”,(b,g,r))
请注意,对于单波段图像,:py:meth:`~PIL.Image.Image.split`返回图像本身。要处理单个色带,您可能需要先将图像转换为“RGB”。
几何变换
的:吡啶:类:`PIL.Image.Image`类包含的方法 :PY:甲基:`〜PIL.Image.Image.resize`和:吡啶:甲基:`〜PIL.Image.Image.rotate`图像。前者采用一个元组给出新的大小,后者采用逆时针方向的角度。
简单的几何变换
out = im.resize((128,128))
out = im.rotate(45)逆时针方向#度
要以90度的步长旋转图像,您可以使用 :py:meth:`~PIL.Image.Image.rotate`方法或 :py:meth:`~PIL.Image.Image.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)
如果expand标志为true,则可以使用:py:meth:`~PIL.Image.Image.rotate`操作以相同的方式执行 操作,以对图像的大小提供相同的更改。
可以通过:py:meth:`~PIL.Image.Image.transform`方法执行更一般的图像转换形式 。
颜色变换
Python Imaging Library允许您使用:py:meth:`~PIL.Image.Image.convert`方法在不同像素表示之间转换图像。
在模式之间转换
来自PIL导入图片
im = Image.open(“hopper.ppm”)。convert(“L”)
该库支持每种支持模式与“L”和“RGB”模式之间的转换。要在其他模式之间进行转换,您可能必须使用中间图像(通常为“RGB”图像)。
图像增强
Python Imaging Library提供了许多可用于增强图像的方法和模块。
过滤器
的:吡啶:MOD:`〜PIL.ImageFilter`模块包含一些预先定义的增强滤波器可以与被使用 :吡啶:甲基:`〜PIL.Image.Image.filter`方法。
应用过滤器
来自PIL导入ImageFilter
out = im.filter(ImageFilter.DETAIL)
点操作
的:吡啶:甲基:`〜PIL.Image.Image.point`方法可用于转换的图像(例如图像对比度操纵)的像素值。在大多数情况下,可以将期望一个参数的函数对象传递给此方法。根据该功能处理每个像素:
应用点变换
#将每个像素乘以1.2
out = im.point(lambda i:i * 1.2)
使用上述技术,您可以快速将任何简单表达式应用于图像。您还可以组合:py:meth:`~PIL.Image.Image.point`和 :py:meth:`~PIL.Image.Image.paste`方法来有选择地修改图像:
处理个别乐队
#将图像分割成单独的波段
source = im.split()
R,G,B = 0,1,2
#选择红色小于100的区域
mask = source [R] .point(lambda i:i <100和255)
#处理绿色乐队
out = source [G] .point(lambda i:i * 0.7)
#将已处理的条带粘贴回来,但仅限于红色<100的情况
来源[G] .paste(out,None,mask)
#构建一个新的多波段图像
im = Image.merge(im.mode,source)
请注意用于创建掩码的语法:
imout = im.point(lambda i:表达式和255)
Python仅在确定结果时评估逻辑表达式的部分,并返回作为表达式结果检查的最后一个值。因此,如果上面的表达式为false(0),Python不会查看第二个操作数,因此返回0.否则返回255。
增强
对于更高级的图像增强,您可以使用 :py:mod:`~PIL.ImageEnhance`模块中的类。从图像创建后,可以使用增强对象快速尝试不同的设置。
您可以通过这种方式调整对比度,亮度,色彩平衡和清晰度。
增强图像
来自PIL导入ImageEnhance
enh = ImageEnhance.Contrast(im)
enh.enhance(1.3).show(“对比度提高30%”)
图像序列
Python Imaging Library包含对图像序列(也称为动画格式)的一些基本支持。支持的序列格式包括FLI / FLC,GIF和一些实验格式。TIFF文件还可以包含多个帧。
打开序列文件时,PIL会自动加载序列中的第一帧。您可以使用seek和tell方法在不同的帧之间移动:
阅读序列
来自PIL导入图片
im = Image.open(“animation.gif”)
im.seek(1)#跳到第二帧
尝试:
而1:
im.seek(im.tell()+ 1)
#做点什么
除了EOFError:
传递#序列结束
如本例所示,当序列结束时,你会得到一个:py:exc:`EOFError`异常。
请注意,当前版本的库中的大多数驱动程序只允许您搜索下一帧(如上例所示)。要回放文件,您可能必须重新打开它。
以下类允许您使用for语句循环遍历序列:
使用ImageSequence Iterator类
来自PIL导入ImageSequence
for ImageSequence.Iterator(im)中的帧:
#...做一些框架......
后记打印
Python Imaging Library包含在Postscript打印机上打印图像,文本和图形的功能。这是一个简单的例子:
绘制Postscript
来自PIL导入图片
来自PIL import PSDraw
im = Image.open(“hopper.ppm”)
title =“hopper”
box =(1 * 72,2 * 72,7 * 72,10 * 72)#in points
ps = PSDraw.PSDraw()#default是sys.stdout
ps.begin_document(标题)
#绘制图像(75 dpi)
ps.image(box,im,75)
ps.rectangle(盒)
#draw title
ps.setfont(“HelveticaNarrow-Bold”,36)
ps.text((3 * 72,4 * 72),标题)
ps.end_document()
更多关于阅读图像
如前所述,:py:mod:`~PIL.Image`模块的:py:func:`~PIL.Image.open`函数 用于打开图像文件。在大多数情况下,您只需将文件名作为参数传递:
来自PIL导入图片
im = Image.open(“hopper.ppm”)
如果一切顺利,结果是:py:class:`PIL.Image.Image`对象。否则,引发:exc:`IOError`异常。
您可以使用类似文件的对象而不是文件名。该对象必须实现:py:meth:`~file.read`,:py:meth:`~file.seek`和 :py:meth:`~file.tell`方法,并以二进制模式打开。
从打开的文件中读取
来自PIL导入图片
打开(“hopper.ppm”,“rb”)为fp:
im = Image.open(fp)
要从字符串数据中读取图像,请使用:py:class:`~StringIO.StringIO` 类:
从字符串中读取
import StringIO
im = Image.open(StringIO.StringIO(buffer))
请注意,库seek(0)
在读取图像标题之前会对文件进行倒带(使用)。此外,当读取图像数据时(通过加载方法)也将使用搜索。如果图像文件嵌入在较大的文件中,例如tar文件,则可以使用:py:class:`~PIL.ContainerIO`或 :py:class:`~PIL.TarIO`模块来访问它。
从tar档案中读取
来自PIL import Image,TarIO
fp = TarIO.TarIO(“Tests / images / hopper.tar”,“hopper.jpg”)
im = Image.open(fp)
控制解码器
某些解码器允许您在从文件中读取图像时操作图像。这通常可用于在创建缩略图时(当速度通常比质量更重要时)加速解码并打印到单色激光打印机(当只需要图像的灰度版本时)。
的:吡啶:甲基:`〜PIL.Image.Image.draft`方法操纵打开但还没有加载的图像,因此给定的模式和大小尽可能地匹配。这是通过重新配置图像解码器来完成的。
阅读草稿模式
这仅适用于JPEG和MPO文件。
来自PIL导入图片
来自__future__ import print_function
im = Image.open(文件)
print(“original =”,im.mode,im.size)
im.draft(“L”,(100,100))
print(“draft =”,im.mode,im.size)
这打印像:
原始= RGB(512,512)
吃水= L(128,128)
请注意,生成的图像可能与请求的模式和大小不完全匹配。要确保图像不大于给定大小,请改用缩略图方法。