Pillow 是一个第三方 Python 模块,用于处理图像文件。该模块包含一些函数,可以很容易地裁剪图像、调整图像大小,以及编辑图像的内容。
1. 计算机图像基础
1.1 RGBA
计算机程序通常将图像中的颜色表示为 RGBA 值。 RGBA 值是一组数字,指定顔色中的红、绿、蓝和 alpha(透明度)的值。
在 Pillow 中, RGBA 值表示为四个整数值的元组。例如,红色表示为(255,0, 0, 255)。同时,pillow也使用标准的颜色名称代替常见颜色的RGBA值:
名称 | RGBA值 |
---|---|
White | (255, 255, 255, 255) |
Red | (255, 0, 0, 255) |
Green | (0, 128, 0, 255) |
Blue | (0, 0, 255, 255) |
Gray | (128, 128, 128, 255) |
Yellow | (255, 255, 0, 255) |
Black | (0, 0, 0, 255) |
Purple | (128, 0, 128, 255) |
1.2 坐标和box元组
图像像素用 x 和 y 坐标指定,分别指定像素在图像中的水平和垂直位置。原点是位于图像左上角的像素,用符号(0, 0)指定。第一个 0 表示 x 坐标,它以原点处为 0,从左至右增加。第二个 0 表示 y 坐标,它以原点处为 0,从上至下增加。
许多 Pillow 函数和方法需要一个矩形元组参数。这意味着 Pillow 需要一个四个整坐标的元组,表示图像中的一个矩形区域。四个整数按顺序分别是:
- 左:该矩形的最左边的 x 坐标。
- 顶:该矩形的顶边的 y 坐标
- 右:该矩形的最右边右面一个像素的 x 坐标。此整数必须比左边整数大
- 底:该矩形的底边下面一个像素的 y 坐标。此整数必须比顶边整数大。
2. Pillow图像处理
2.1 加载图像和Image对象
要加载图像,就从 Pillow 导入 Image 模块,并调用 Image.open(),传入图像的文件名。
通过 save()方法,对 Image 对象的所有更改都可以保存到图像文件中(也是任何格式)。所有的旋转、调整大小、裁剪、绘画和其他图像操作,都通过这个 Image 对象上的方法调用来完成。
from PIL import Image
cat = Image.open('media/cat.png') # 打开图像文件
# 打印图像属性
print(cat.size) # 宽,高元组
print(cat.filename)
print(cat.format)
cat.save('media/cat.png')
Image.new()函数,它返回一个表示空白的Image对象,其参数有:
- 字符串’RGBA’,将颜色模式设置为 RGBA(还有其他模式,但本书没有涉及)。
- 大小,是两个整数元组,作为新图像的宽度和高度。
- 图像开始采用的背景颜色,是一个表示 RGBA 值的四整数元组
from PIL import Image
im = Image.new('RGBA', (10,20), 'black')
im.save('media/new.png')
2.2 裁剪图片
Image 对象的 crop()方法接受一个矩形元组,返回一个 Image 对象,表示裁剪后的图像。 裁剪不是在原图上发生的,也就是说,原始的 Image 对象原封不动, crop()方法返回一个新的 Image 对象。
from PIL import Image
cat = Image.open('media/cat.png')
cropcat=cat.crop((335,345,565,560))
cropcat.save('media/cropcat.png')
2.3 复制粘贴图像
copy()方法返回一个新的 Image 对象,它和原来的 Image 对象具有一样的图像。
paste()方法在 Image 对象调用,将另一个图像粘贴在它上面。
# 复制粘贴图像
copycat=cat.copy()
copycat.paste(cropcat, (0,0))
2.4 调整图像大小
resize()方法在 Image 对象上调用,返回指定宽度和高度的一个新 Image 对象。它接受两个整数的元组作为参数,表示返回图像的新高度和宽度。
2.5 旋转和翻转
图像可以用 rotate()方法旋转,该方法返回旋转后的新 Image 对象,并保持原始 Image 对象不变。 rotate()的参数是一个整数或浮点数,表示图像逆时针旋转的度数。
利用 transpose()方法,还可以得到图像的“镜像翻转”。必须向transpose()方法传入 Image.FLIP_LEFT_RIGHT 或 Image.FLIP_TOP_BOTTOM表示水平翻转还是垂直翻转。
2.6 修改单个像素
通过 getpixel()和 putpixel()方法可以获取和修改单个像素。它们都接受一个元组,表示像素的 x 和 y 坐标。 putpixel()方法还接受一个元组,作为该像素的颜色。
im.putpixel((x,y), (210, 210, 210))
im.getpixel((0, 0))
>>>(210, 210, 210, 255)
3. pillow绘图
将Image 对象传入 ImageDraw.Draw()函数,得到一个 ImageDraw 对象。这个对象有一些方法,可以在 Image 对象上绘制形状和文字。
3.1 绘制形状
下面的 ImageDraw 方法在图像上绘制各种形状。这些方法的 fill 和 outline 参数是可选的,如果未指定,默认为白色。
- 点: point(xy, fill)方法绘制单个像素。 xy 参数表示要画的点的列表。该列表可以是 x 和 y 坐标的元组的列表,例如[(x, y), (x, y), …],或是没有元组的 x 和 y 坐标的列表,例如[x1, y1, x2, y2, …]。 fill 参数是点的颜色,要么是一个 RGBA 元组,要么是颜色名称的字符串。
- 线: line(xy, fill, width)方法绘制一条线或一系列的线。 xy 要么是一个元组的列表,例如[(x, y), (x, y), …],要么是一个整数列表,例如[x1, y1, x2, y2, …]。每个点都是正在绘制的线上的一个连接点。可选的 width 参数是线的宽度,如果未指定,缺省值为 1
- 矩形: rectangle(xy, fill, outline)方法绘制一个矩形。 xy 参数是一个矩形元组,形式为(left,top, right, bottom)。可选的 fill 参数是颜色,将填充该矩形的内部。可选的 outline 参数是矩形轮廓的颜色。
- 椭圆: ellipse(xy, fill, outline)方法绘制一个椭圆。如果椭圆的宽度和高度一样,该方法将绘制一个圆。 xy 参数是一个矩形元组(left, top, right, bottom)。
- 多边形: polygon(xy, fill, outline)方法绘制任意的多边形。 xy 参数是一个元组列表,例如 [(x, y), (x, y), …],或者是一个整数列表,例如[x1, y1, x2, y2, …],表示多边形边的连接点。最后一对坐标将自动连接到第一对坐标.
Example:
from PIL import Image, ImageDraw
im = Image.new('RGBA', (200, 200), 'white')
draw = ImageDraw.Draw(im)
draw.line([(0, 0), (199, 0), (199, 199), (0, 199), (0, 0)], fill='black')
draw.rectangle((20, 30, 60, 60), fill='blue')
draw.ellipse((120, 30, 160, 60), fill='red')
draw.polygon(((57, 87), (79, 62), (94, 85), (120, 90), (103, 113)),fill='brown')
im.save('media/drawing.png')
3.2 绘制文字
ImageDraw 对象text()方法,用于在图像上绘制文本。 text()方法有 4 个参数: xy、 text、 fill 和 font。
- xy 参数是两个整数的元组,指定文本区域的左上角。
- text 参数是想写入的文本字符串。
- 可选参数 fill 是文本的颜色。
- 可选参数 font 是一个 ImageFont 对象,用于设置文本的字体和大小。可以调用 ImageFont.truetype()函数,第一个参数是字符串,表示字体的 TrueType 文件;第二个参数是一个整数,表示字体大小。
Example:
draw.text((20, 150), 'Hello', fill='purple')
fontsFolder = 'FONT_FOLDER' # e.g. ‘/Library/Fonts’
arialFont = ImageFont.truetype(os.path.join(fontsFolder,'arial.ttf'), 32)
draw.text((100, 150), 'Howdy', fill='gray', font=arialFont)