Image类的使用
在Python图像库里面,非常重要的一个类就是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属性标志着图像的来源。如果图像不是来源于文件,那么它会设置为None。size属性是一个表示图像像素的长和宽的二元组。mode属性定义图像的频域和名称,以及像素类型及深度。通常mode为“L”表示灰度图像,“RGB”为彩色图像,“CMKY”为pre-press图像。
如果不能打开文件,那么“IOError”异常被激活。
一旦你用Image类做了实例化,你可以用该类里面已经定义的方法处理及操作图像。例如,我们可以显示刚才加载的图像:
>>> im.show()
注意:标准版本中show()不是很有用,因为它只是将图像暂时保存在一个文件中,并且调用XV显示图像。如果你没有安装xv,那么它将不会工作.但是它工作时,却是非常的方便你调试和测试。
读取和写入图像
Python库支持非常广泛的图像格式。利用Image模型里面的open()函数从磁盘中读取图像。你不需要知道打开的文件格式。库会根据图像内容自动获得图像格式。
利用Image类里面的save()方法保存文件。当保存文件时,文件名就显得尤为重要。除非你标明格式,否则库会利用所要保存到的文件的扩展名命名文件格式。
将文件转换为JPEG格式
from __futurn__ import print_function
import os, sys
from PIL import Image
for 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_function
import os, sys
form PIL import Image
size = (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 convert", infile)
需要着重注意的是库文件不会解码或加载raster数据,除非很必要。当你打开一个文件时,文件的头被读取,以便于确定文件格式和提取文件属性,如模式、大小或其他一些需要的属性。但是其他的一些属性不会被处理。
这就意味着,打开文件是一个快速的操作,它与文件类型及压缩类型无关。下面是一个快速识别图像数据集的简单脚本:
form __futurn__ import print_function
import sys
from PIL import Image
for infile in sys.argv[1:]:
try:
with Image.open(infile) as im:
print(infile, im.format, "%d%d" % im.size, im.mode)
except IOError:
pass
剪切、粘贴、合并图像
Image 类包含了一些方法可以对图像区域进行操作。用crop()方法来提取图像的一个方形子图:
复制一个图像的方形子块
box = (100, 100, 400, 400)
region = im.crop(box)
区域被定义为一个4元组,它是一个表示(左,上,右,下)的坐标系。Python图像库利用(0,0)坐标表示左上角。注意坐标系的位置是用像素定义的,因此上面提到的区域准确定义为300*300像素。
上述区域现在就可以进行粘贴合并操作了。
处理和粘贴图像区域
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将从已经由第一个粘贴修改的图像的版本中裁剪出来。对于更高的技巧,粘贴方法也可以使用透明度掩码作为可选参数。在该掩码中,值255表示粘贴的图像在该位置是不透明的,(即粘贴的图像应被原样使用)。值0表示粘贴的图像完全透明。中间值表示不同的透明度。例如,粘贴RGBA图像并将其作掩码将粘贴图像的不透明部分,而不是其透明背景。
source URL:http://pillow.readthedocs.io/en/latest/handbook/tutorial.html