Python Imaging Library 中文手册 (2003 版)

这是PIL的官方手册,2003年9月17日发布。这个版本涵盖 PIL 1.1.4的全部内容,同时也包括部分1.1.5新增的内容。

原版出处:http://www.pythonware.com/library/pil/handbook/

TableOfContents

Part I. 介绍

Part II. 模块参考手册

Part III. 工具参考手册

附录

Python Imaging Library 概述

介绍

图像归档处理

图像显示

图像处理

这个库提供了基本的图像处理功能,包括点操作、内建滤波核滤波操作以及颜色空间变换操作。

入门导引

使用 Image 类

Python Imaging Library中最重要的类是Image 类,定义在与它同名的模块中。有多种创建这个类的对象的方法:或者从文件中读取得到,或者从其他图像经处理得到,或者从头创建。

要从文件读取图像,可以使用Image 模块提供的open 函数。

   1 >>> import Image
   2 >>> im = Image.open("lena.ppm")

如果成功,这个函数返回一个Image 对象。可以使用这个对象的属性来检查文件的内容。

   1 >>> print im.format, im.size, im.mode
   2 PPM (512, 512) RGB

format 属性表示图像的原始格式。如果图像不是从文件中读取的,则它被设置成 None。size 属性是一个2-tuple,表示图像的宽度和高度 (以像素为单位)。mode 属性定义图像的通道的数量与名字,同时也包括像素的类型和颜色深度信息。通常来说,灰度图像的mode是"L" (luminance),真彩色图像的mode是 "RGB" ,pre-press图像的mode是"CMYK"。

如果文件不能打开,会抛出一个IOError 异常。

如果已经创建好了一个Image 类的对象,接下来就可以使用这个类定义的方法来处理和操作图像了。比如说,显示刚才打开的文件:

(show 的标准实现不是很高效,它先将图像保存成一个临时文件,然后调用 xv 程序来显示图像。如果你没有安装xv ,它甚至不能工作。然而如果它可用,它将是非常方便的测试和除错的工具。)

接下来的内容将对库中提供的一些功能进行一个概述。

读写图像

Python Imaging Library 支持很广泛的图象文件格式。要从磁盘上读取文件,使用 Image 模块提供的open 函数。你不必了解你要打开的文件的格式,库会自动根据文件的内容来确定图像的格式。

要保存文件,使用Image 类的save 方法。保存文件时,文件名是非常重要的。除非你制定了格式,否则库会根据文件扩展名来决定使用哪种格式存储。

1. 将文件转换成 JPEG

import os, sys import Image

for infile in sys.argv[1:]:

save 方法可以带第二个参数,用来显式指定文件的格式。如果要使用非标准的扩展名,就必须这样指定文件格式:

2. 创建 JPEG 缩略图

import os, sys import Image

size = 128, 128

for infile in sys.argv[1:]:

有一点非常重要的需要注意的是,除非到了迫不得已的时候,库不会装载或者解码光栅数据。当打开一个文件的时候,库会读取文件头以获得文件格式、颜色模式、图像大小等属性,但是文件剩余的部分不会马上处理。

这意味着,文件打开操作是很快的,它与文件的大小、压缩的类型没有关系。这里是一个快速识别一系列图像文件的简单例子:

3. 识别图像文件

import sys import Image

for infile in sys.argv[1:]:

裁剪、粘贴和合并图像

Image 类提供一些对图像中的区域进行处理的方法。要从图像中提取一块子矩形区域,使用 crop 方法。

1. 从图像中拷贝一块子矩形区域

区域由4元组定义,表示为 (left, upper, right, lower)。 Python Imaging Library 使用左上角为 (0, 0)的坐标系统。同时要注意,坐标指向像素之间的位置,因此上述例子中描述的区域的大小为300x300像素。

区域图像能够经过某些特定的处理并粘回原处。

2. 处理一块子矩形区域,并粘回原处

当把区域粘回原处时,指定的区域大小必须和区域图像的大小相同。此外,区域不能超出图像的边界。然而,原始图像的模式和区域图像的模式不必相同。如果不相同,区域图像的模式在粘贴时会被自动转换 (细节请查看后面有关颜色变换 的章节)。

这里有另一个例子:

3. 滚动一幅图像

def roll(image, delta):

更高级的技巧是,paste方法可以带一个透明掩模作为可选参数。在这个掩模中,像素值255 代表被粘贴的图像在那个位置上是不透明的。 (就是说,此处显示被粘贴的图像上的值。)像素值 0 表示被粘贴的图像是完全透明的。在它们之间的值表示不同程度的透明度。

Python Imaging Library 还允许对一幅多通道图像(比如RGB图像)的单个通道进行操作。split方法能够创建一组新的图像,每一幅都是原来多通道图像的一个通道。merge函数以一个模式和一组图像的元组为参数,把这些图像组成一幅新图像。下面的例子实现交换一幅RGB图像的三个通道:

4. 分离与合并通道

r, g, b = im.split() im = Image.merge("RGB", (b, g, r))

几何变换

Image 类包含resize 和 rotate 方法来缩放和旋转图像。前者带一个tuple类型的参数来表示新的图像大小,后者带一个逆时针旋转的角度值作为参数。

1. 简单的几何变换

out = im.resize((128, 128)) out = im.rotate(45) # degrees counter-clockwise

如果要将图像旋转90度的整数倍,可以使用rotate 或者transpose 方法。后者还可以用来水平或者垂直镜像一幅图像。

2. 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)

There's no difference in performance or result between transpose(ROTATE) and corresponding rotate operations.

一个更通用的变换方法是 transform,在参考手册中有对它的详细叙述。

颜色变换

Python Imaging Library提供convert函数,可以将图像在不同的像素格式间转换。

1. 转换图像颜色模式

库支持在所有支持的颜色模式和"L"以及"RGB"之间的直接转换。其他颜色模式之间的转换要借助于中间图像模式(通常是"RGB" 模式)。

图像增强

Python Imaging Library提供一系列的函数和模块来进行图像增强。

1. 滤波器

ImageFilter 模块中包含一些预定义的增强滤波器,用filter 方法来使用滤波器。

1.1. 使用滤波器

import ImageFilter out = im.filter(ImageFilter.DETAIL)

2. 点操作

point 方法可以对图像的像素值进行变换(比如对比度变换)。在大多数场合,使用函数对象(带一个参数)作为参数传递给point方法。每一个像素使用这个函数对象进行变换:

2.1. 使用点变换

# multiply each pixel by 1.2 out = im.point(lambda i: i * 1.2)

用上面的技巧,你可以对图像用任何简单的表达式进行变换。你还可以结合使用point 和paste 方法来有选择的改变一幅图像:

2.2. 处理单个通道

# split the image into individual bands source = im.split()

R, G, B = 0, 1, 2

# select regions where red is less than 100 mask = source[R].point(lambda i: i < 100 and 255)

# process the green band out = source[G].point(lambda i: i * 0.7)

# paste the processed band back, but only where red was < 100 source[G].paste(out, None, mask)

# build a new multiband image im = Image.merge(im.mode, source)

注意用来创建mask的语法:

Python 只计算一个逻辑表达式的一部分,只要能确定表达式的结果其他部分就不进行计算了,并把最后计算得到的值作为表达式的值返回。因此,如果上述expression是false(0),Python就不会检查第二个参数,因此返回0,否则返回255。

3. 增强

对于更多更高级的图像增强,可以使用ImageEnhance 模块。一旦从图像上创建了增强对象,你就可以尝试采用各种不同的参数进行快速的增强处理了。

你能通过这样的方法来调整图像的对比度、亮度、色彩平衡和锐度。

3.1. 增强图像

import ImageEnhance

enh = ImageEnhance.Contrast(im) enh.enhance(1.3).show("30% more contrast")

图像序列

Python Imaging Library 包含对于图像序列 (也称作动画 格式)的基本支持。支持的序列格式包括 FLI/FLC, GIF, 和一些试验性的格式。TIFF 文件也能包含超过一帧的图像。

当你打开一个序列文件时,PIL 会自动加载序列中的第一帧。你可以使用seek 和tell 方法在不同帧之间移动:

1. 读取图像序列

import Image

im = Image.open("animation.gif") im.seek(1) # skip to the second frame

try:

except EOFError:

正如这个例子所示,当序列结束时,你会得到一个EOFError 异常。

注意,当前版本库的绝大多数驱动只允许你移动到下一帧(如上面例子所示)。如果要回到文件的开头,你可能必须重新打开它。

下面的迭代类让你能够使用for循环来迭代图像序列:

2. 一个序列迭代类

class ImageSequence:

for frame in ImageSequence(im):

Postscript格式打印

Python Imaging Library提供将图像、文字和图形输出到Postscript打印机的功能。这是一个简单的例子:

1. Drawing Postscript

import Image import PSDraw

im = Image.open("lena.ppm") title = "lena" box = (1*72, 2*72, 7*72, 10*72) # in points

ps = PSDraw.PSDraw() # default is sys.stdout ps.begin_document(title)

# draw the image (75 dpi) ps.image(box, im, 75) ps.rectangle(box)

# draw centered title ps.setfont("HelveticaNarrow-Bold", 36) w, h, b = ps.textsize(title) ps.text((4*72-w/2, 1*72-h), title)

ps.end_document()

2. 更多关于读取图像

前面叙述过,Image模块的open函数用来打开一个图像文件。在大多数情况,你只用简单的把文件名传给它就可以了:

im = Image.open("lena.ppm")

如果一切正常,结果是一个Image 对象。否则,会抛出一个IOError 异常。

你可以使用一个类似文件的对象来代替文件名。这个对象必须实现read、 seek 和 tell 方法,并以二进制方式打开。 从一个打开的文件读取

fp = open("lena.ppm", "rb") im = Image.open(fp)

要从字符串数据中读取一幅图像,可以使用StringIO 类: 从一个字符串读取

import StringIO

im = Image.open(StringIO.StringIO(buffer))

注意库在读取图像头之前,会先移动到文件头 (用seek(0))。另外,在图像数据被读取 (通过 load 方法)以后,seek方法也会被调用。如果图像文件被嵌在一个更大的文件里面,比如tar文件,你可以使用ContainerIO 或者TarIO 模块来访问它。 从一个tar压缩文档读取

import TarIO

fp = TarIO.TarIO("Imaging.tar", "Imaging/test/lena.ppm") im = Image.open(fp)

3. 控制解码器

一些解码器允许你在从文件读取图像的同时对图像进行操作。这个特性常常被用来在创建缩略图(创建缩略图的速度通常比缩略图的质量更重要)或者打印到一个黑白激光打印机(只需要图像的灰度信息)时加速图像的解码。

draft 方法能够操作一个没有被载入数据的图像对象,使得它能够尽可能与需要的模式和大小相匹配。这通过重新配置图像解码器来实现。 以草稿方式读取

im = 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)

注意,最终获得图像可能与要求的模式和大小不完全一致。如果要求生成的图像不能超过给定的大小,可以使用thumbnail方法来代替。

ch3n2k.com | Copyright (c) 2004-2020 czk.