1.Image类的使用
加载图片:
from PIL import Image
im = Image.open(r"test.jpg")
查看图片的格式、尺寸和模式,模式包括灰度(L)、真彩(RGB)和印刷(CMYK):
print(im.format, im.size, im.mode)
显示图片:
im.show()
2.读写图片
读取时无需指定图片类型,PIL会自动识别。使用save()
方法保存图片,除非指定格式,图片将以输入图片扩展名保存。
2.1将图片转为JPEG
from __future__ 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()
的第二个参数中指定图片的保存类型。
2.2创建缩略图
im.thumbnail(size)
3.剪切、粘贴和合并图片
用crop()
方法提取图片特定区域
3.1从图片中复制一块子图
box = (100, 100, 400, 400)
region = im.crop(box)
区域框的坐标为左、上、右、下,坐标系以左上角为(0,0)点。
3.2将子区域粘贴回原图
region = region.transpose(Image.ROTATE_180)
im.paste(region, box)
将子图粘贴回原图。若box为四元组,子图的尺寸必须完全匹配给定的区域;若box参数为二元组,则只需指定左上角;若不指定则粘贴至原图左上角。
更多的示例:
3.2.1.横向滚动图片:
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))
image.paste(part1, (xsize-delta, 0, xsize, ysize))
image.paste(part2, (0, 0, xsize-delta, ysize))
return image
paste
方法可以接受一个透明的遮罩层作为可选参数。在mask
中,值为255表示该位置上粘贴的图片是不透明的,而0意味着完全透明,即用0~255表现不同的透明度。例如,在粘贴一张RGBA图片的同时也使用它作为mask
参数,则只会粘贴它的不透明部分,而忽略透明背景。
3.2.2拆分、合并图像通道
使用split
方法拆分通道,使用merge
方法合并通道。例如将图片的B和R通道对换。
r, g, b = im.split()
im = Image.merge("RGB", (b, g, r))
4.几何变换
PIL.Image.Image
类包含方法来resize()
和rotate()
一张图片,前者接受一个元组作为新的尺寸,后者则是一个逆时针的角度。
4.1.简单几何变换
out = im.resize((128, 128))
out = im.rotate(45) # degrees counter-clockwise
4.2.转置图片
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)
的操作等同于rotate()
方法,前提是rotate()
的参数expand
设为True
,这样会对图片的尺寸作相同的变换。
5.颜色变换
5.1转换色彩模式
from PIL import Image
im = Image.open("hopper.ppm").convert("L")
将RGB转换成灰度图。如果要在其他格式间转换,可能需要先将它们转换成中间格式,例如RGB。
6.图像增强
6.1.过滤器
ImageFilter
模块中包含一系列可被filter()
方法使用的预定义的过滤器。
6.1.1使用过滤器
from PIL import ImageFilter
out = im.filter(ImageFilter.DETAIL)
6.2.像素级操作
point()
方法可以转换图像的像素点的值。大多数情况下,只包含一个参数的函数可以传递给这个方法,每个像素都会被该函数处理。
6.2.1 实施点转换
out = im.point(lambda i: i * 1.2)
6.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)
使用下列语法来创建遮罩:
imout = im.point(lambda i: expression and 255)
即遮罩层中符合expression
的设为255,不符合的设为False。
7.图片序列
当打开一张动图时,PIL自动加载序列的第一帧。可以使用seek
和tell
方法在不同帧之间移动。
7.1 读取序列
from PIL import Image
im = Image.open("animation.gif")
im.seek(1) # skip to the second frame
try:
while 1:
im.seek(im.tell()+1)
# do something to im
except EOFError:
pass # end of sequence
7.2 使用ImageSequence迭代器
可直接在for循环中遍历
from PIL import Image,ImageSequence
im = Image.open("timg.gif")
for frame in ImageSequence.Iterator(im):
frame.show()
8.Postscript打印
Postscript是Adobe的页面描述语言。
8.1 绘制Postscript
from PIL import Image
from 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 is sys.stdout
ps.begin_document(title)
# draw the image (75 dpi)
ps.image(box, im, 75)
ps.rectangle(box)
# draw title
ps.setfont("HelveticaNarrow-Bold", 36)
ps.text((3*72, 4*72), title)
ps.end_document()
9.更多图像读取方式
9.1 从打开文件中读取
from PIL import Image
with open("hopper.ppm", "rb") as fp:
im = Image.open(fp)
9.2 从字符串中读取
from PIL import Image
import StringIO
im = Image.open(StringIO.StringIO(buffer))
9.3 从压缩文件中读取
from PIL import Image, TarIO
fp = TarIO.TarIO("Tests/images/hopper.tar", "hopper.jpg")
im = Image.open(fp)
10.控制解码器
部分解码器支持在读取文件处理图片,这常用于加速创建缩略图。
draft()
方法处理一张打开但还未加载的图片,它会输出与给定模式和尺寸尽可能接近的结果。
10.1 以草稿模式读取
from PIL import Image
im = Image.open('test.jpg')
print("original =", im.mode, im.size)
im.draft("L", (100, 100))
im.show()
print("draft =", im.mode, im.size)
draft
的结果可能并不精确匹配需要的模式和尺寸,要确保输出结果不大于给定的尺寸,请使用thumbnail
方法。
更多用法请参照官方文档