使用 Python Image Library (PIL), 需要先导入相关模块:
import Image
如何加载图片:
im = Image.open(r“D:/www/icon_1.jpg“)
如果加载发生错误,会引发 IOError.
打印出图片的格式、大小、模式
print im.format, im.size, im.mode
图片的显示,用 show() 方法
im.show()
show() 需要调用 xv 程序,适合调试和测试。在 Windows 上通常是调用相关的关联程序来打开(我的是 AcdSee)。注意这个方法在显示前会自动创建临时文件。
图片的保存
im.save(r“d:/www/icon_1.gif“)
默认会自动根据目标文件扩展名判断保存的格式,但可以给 save 方法提供第二个参数指定格式。
创建缩略图
im.thumbnail((128, 128))
im.save(r“d:/www/icon_1.thumbnail“, “JPEG“)
图片的区域裁剪
用 crop 方法可以裁剪图片中的一个矩形区域
box = (100, 100, 400, 400) # (left, upper, right, lower)
region = im.crop(box)
图片的粘贴
处理上面的区域,然后粘贴回来:
region = region.transpose(Image.ROTATE_180)
im.paste(region, box)
需要注意粘贴的时候目标区域大小要和被粘贴的图片一样大。
高级技巧:paste 方法可以指定可选参数,设定透明度(0~255).
PIL 还可以处理 multi-band 图片的每个独立的 band. 比如 RGB. 然后用 merge 函数重新合并:
r, g, b = im.split()
im = Image.merge(“RGB“, (b, g, r))
Image.open 方法可以从 file like object 中加载,如 StringIO.
下面这个例子在 web 中上传图片保存之前,预先判断其图片文件大小:
file_obj = request.FILES.get(‘avator‘, None)
if file_obj:
im = Image.open(StringIO.StringIO(file_obj["content"]))
if im.size[0] > 150 or im.size[1] > 150:
avator_error = ‘图片尺寸最大为 150 * 150‘
缩放
out = im.resize((128, 128))
逆时针旋转一定的度数
(需要注意这个方法不会在 img 对象上做 in-place 的操作,而是返回一个转换后的新对象:
out = out.rotate(45)
要按 90 度的整数倍来旋转图片的话,也可以用 transpose 方法
transpose 方法也可以对图片沿 x 或 y 轴翻转
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)
颜色模式转换
im = im.convert(“L“)
如果要在其他模式之间转换,可能需要通过中间模式转换一次(比如可以通过 RGB)
图形增强功能
1. 滤镜
im = im.filter(ImageFilter.DETAIL)
这个功能好像是“细节增强”,试了一下发现变的难看了。
2. 点操作
针对每个像素的操作。通常具有一个参数的函数作为参数:
out = im.point(lambda i: i*1.2)
这个操作改变图片的对比度,对每个像素乘以 1.2 (变得亮一些了)
结合 point 和 paste 可以对图片进行针对性的修改操作,例如:
im = Image.open(r“c:/testimg/a.jpg“)
source = im.split()
R,G,B = 0,1,2
# 选择红色值小于 100 的那些区域
mask = source[R].point(lambda i: i / 100 and 255)
# 处理绿色
out = source[G].point(lambda i: i * 0.7)
# 将红色粘贴回来,但仅仅对红色大于 100 的那些像素而言
source[G].paste(out, None, mask)
# 创建一个新的 multiband image
im = Image.merge(im.mode, source)
im.save(r“c:/testimg/e.jpg“)
3. 其他一些图片增强的方法
使用 ImageEnhance 模块中的一些类来完成。
可以用于调整对比度(contrast), 亮度(brightness),颜色对比(color balance),平滑度(sharpness) 等内容。
例:
import ImageEnhance
im = Image.open(r“c:/testimg/a.jpg“)
enh = ImageEnhance.Contrast(im)
enh.enhance(1.3).show(“30% more contrast“)
图片序列(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
print “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):
print “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)
print “original =“, im.mode, im.size
im.draft(
“L“, (100,100))
print “draft =“, im.mode, im.size
这样会输出类似下面的结果:
origial = RGB (512, 512)
draft = L (128, 128)
注意,草稿模式打开的结果图片不一定符合指定的模式和尺寸。如果要确保图片不大于指定尺寸,使用 thumbnail 方法。