图片序列
(Image Sequences,也叫动画格式, animation formats)
PIL 对图片序列有一些基础的支持。支持 FLI/FLC, GIP 和其他一些格式,TIFF 文件也可以包含多个帧。
打开文件时,PIL 自动加载第一帧,可以用 seek 和 tell 方法来在帧之间切换。下列代码是枚举图片序列的每一帧的一个写法:
import
Image
im
=
Image.open(r
”
c:/testimg/ani1.gif
”
)
try
:
while
1
:
im.seek(im.tell()
+
1
)
#
do something to im
”
x
”
except
EOFError:
pass
注意当前的实现中只允许访问下一帧,如果要重头访问,则需要重新 open 图片文件。
用 iterator 类包装后,我们可以用 for 语句来枚举每一个帧:
class
ImageSequence:
def
__init__
(self, im):
self.im
=
im
def
__getitem__
(self, ix):
try
:
if
ix:
self.im.seek(ix)
return
self.im
except
EOFError:
raise
IndexError
for
frame
in
ImageSequence(im):
”
test
”
Postscript Printing
PIL 包含在 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()
#
默认是 sys.stdout
ps.begin_document(title)
#
draw the image (75 dpi)
ps.image(box, im,
75
)
#
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()
关于读取图片的更多话题
前面说过一般用 Image.open(图片文件名) 的方法打开图片,其实不一定要传递图片文件名,也可以是一个实现了 read, seek, tell 方法的对象。该对象将被以二进制模式打开。
可以从字符串中读取图片,用 StringIO 类:
import
StringIO
im
=
Image.open(StringIO.StringIO(buffer))
注意,PIL 库在读取图片头信息时,会重新回到文件开头(用 seek(0) 方法)。在读取图片数据时(load()) 也是如此。如果图片文件比较大,比如在 tar 文件中,可以用 ContainerIO 或 TarIO 模块来访问它。
例子:从 tar 压缩包中读取:
import
TarIO
fp
=
TarIO.TarIO(
”
Imaging.tar
”
,
”
Imaging/test/lena.ppm
”
)
im
=
Image.open(fp)
控制解码器
有些解码器允许一边从文件中读取,一边操作图片。这通常用于在创建缩略图时加速解码操作(速度比图片质量更重要),或者在向单色激光打印机打印的时候(仅需要图片的灰度信息)。
例子:用草稿(draft)模式读取
im
=
Image.open(file)
”
original =
”
, im.mode, im.size
im.draft(
”
L
”
, (
100
,
100
))
”
draft =
”
, im.mode, im.size
这样会输出类似下面的结果:
origial
=
RGB (
512
,
512
)
draft
=
L (
128
,
128
)
注意,草稿模式打开的结果图片不一定符合指定的模式和尺寸。如果要确保图片不大于指定尺寸,使用 thumbnail 方法。