1. 计算机图像基础
1) 颜色和 RGBA 值
RGBA 值是一组数字,指定顔色中的红、绿、蓝和 alpha(透明度)的值。这些值是从 0(根本没有)到 255(最高)的整数。这些 RGBA 值分配给单个像素,像素是计算机屏幕上能显示一种顔色的最小点(你可以想到,屏幕上有几百万像素)。如果颜色的 alpha 值为 0,不论 RGB 值是什么,该颜色是不可见的。
Pillow模块使用了 HTML 使用的标准颜色名称。示例:
Pillow 提供 ImageColor.getcolor()函数,所以你不必记住想用的顔色的 RGBA 值。该函数接受一个颜色名称字符串作为第一个参数,且颜色名称不区分大小写;字符串'RGBA'作为第二个参数,返回一个 RGBA 元组。示例:
>>>from PIL import ImageColor
>>>ImageColor.getcolor('red', 'RGBA')
(255, 0, 0, 255)
>>>ImageColor.getcolor('RED', 'RGBA')
(255, 0, 0, 255)
>>>ImageColor.getcolor('Black', 'RGBA')
(0, 0, 0, 255)
2) 坐标和 Box 元组
Pillow 函数和方法需要一个矩形元组参数。这意味着 Pillow 需要一个四个整坐标的元组,表示图像中的一个矩形区域。四个整数按顺序分别是:
• 左:该矩形的最左边的 x 坐标。
• 顶:该矩形的顶边的 y 坐标。
• 右:该矩形的最右边右面一个像素的 x 坐标。此整数必须比左边整数大。
• 底:该矩形的底边下面一个像素的 y 坐标。此整数必须比顶边整数大。
注意,该矩形包括左和顶坐标,直到但不包括右和底坐标。
2. 用 Pillow 操作图像
从 Pillow 导入 Image 模块,并调用 Image.open(),传入图像的文件名,返回一个Image对象数据类型。后续的许多操作都是基于Image对象。示例:
>>>from PIL import Image
>>>catIm = Image.open('zophie.png')
1) 处理 Image 数据类型
通过Image对象的属性可以获取图像文件的基本信息:它的宽度和高度、文件名和图像格式(如 JPEG、GIF 或 PNG)。示例:
>>> from PIL import Image
>>> catIm =Image.open('zophie.png')
>>> catIm.size
(816, 1088)
>>> catIm.filename
'zophie.png'
>>> catIm.format
'PNG'
>>> catIm.format_ _description
'Portable network graphics'
>>> catIm.save('zophie.jpg')
Pillow 还提供了 Image.new()函数,它返回一个 Image 对象。这很像 Image.open(),不过 Image.new()返回的对象表示空白的图像。Image.new()的参数如下:
• 字符串'RGBA',将颜色模式设置为 RGBA(还有其他模式)。
• 大小,是两个整数元组,作为新图像的宽度和高度。
• 图像开始采用的背景颜色,是一个表示 RGBA 值的四整数元组。如果未指定颜色参数,默认的颜色是不可见的黑色(0,0,0,0)。可以用ImageColor.getcolor()函数的返回值作为这个参数。示例:
>>> from PIL import Image
>>> im = Image.new('RGBA', (100,200), 'purple')
>>> im.save('purpleImage.png')
2) 裁剪图片
裁剪图像是指在图像内选择一个矩形区域,并删除矩形之外的一切。Image对象的crop()接受一个矩形元组,返回一个裁剪后的新的Image对象。
>>>croppedIm = catIm.crop((335, 345, 565, 560))
<PIL.Image.Imageimage mode=RGB size=230x215 at 0x1A1C8AF46D8>
>>>croppedIm.save('cropped.png')
3) 复制和粘贴图像到其他图像
copy()方法返回一个新的 Image 对象,它和原来的 Image 对象具有一样的图像。示例:
>>>catIm = Image.open('zophie.png')
>>>catCopyIm = catIm.copy()
paste()方法在 Image 对象调用,将另一个图像粘贴在它上面。示例:
>>>faceIm = catIm.crop((335, 345, 565, 560))
>>>faceIm.size
(230, 215)
>>>catCopyIm.paste(faceIm, (0, 0))
>>>catCopyIm.paste(faceIm, (400, 500))
>>>catCopyIm.save('pasted.png')
注:
a) 尽管名称是 copy()和 paste(),但 Pillow 中的方法不使用计算机的剪贴板。
b) paste()方法在原图上修改它的 Image 对象。
4) 调整图像大小
resize()方法在 Image 对象上调用,返回指定宽度和高度的一个新 Image 对象。它接受两个整数的元组作为参数,表示返回图像的新高度和宽度。示例:
>>>width, height = catIm.size
>>>quartersizedIm = catIm.resize((int(width / 2), int(height / 2)))
>>>quartersizedIm.save('quartersized.png')
>>>svelteIm = catIm.resize((width, height + 300))
>>>svelteIm.save('svelte.png')
5) 旋转和翻转图像
rotate()方法返回选择后的新Image对象,rotate()的参数是一个整数或浮点数,表示图像逆时针旋转的度数。示例:
>>>catIm.rotate(90).save('rotated90.png')
>>>catIm.rotate(180).save('rotated180.png')
>>>catIm.rotate(270).save('rotated270.png')
当图像旋转 90 度或 270 度时,宽度和高度会变化。如果旋转其他角度,图像的原始尺寸会保持。在Windows 上,使用黑色的背景来填补旋转造成的缝隙。
rotate()方法有一个可选的 expand 关键字参数,如果设置为 True,就会放大图像的尺寸,以适应整个旋转后的新图像。示例:
>>>catIm.rotate(6).save('rotated6.png')
>>>catIm.rotate(6, expand=True).save('rotated6_ _expanded.png')
transpose()方法,还可以得到图像的“镜像翻转”。必须向transpose()方法传入 Image.FLIP_LEFT_RIGHT 或 Image.FLIP_TOP_BOTTOM。示例:
>>>catIm.transpose(Image.FLIP_ _LEFT_ _RIGHT).save('horizontal_ _flip.png')
>>>catIm.transpose(Image.FLIP_ _TOP_ _BOTTOM).save('vertical_ _flip.png')
6) 更改单个像素
单个像素的颜色可以通过getpixel()和putpixel()方法取得和设置。它们都接受一个元组,表示像素的 x 和 y 坐标。putpixel()方法还接受一个元组,作为该像素的颜色。这个顔色参数是四整数RGBA 元组或三整数RGB 元组。示例:
>>> im= Image.new('RGBA', (100, 100))
>>>im.getpixel((0, 0))
(0, 0, 0, 0)
>>> forx in range(100):
for y inrange(50):
im.putpixel((x, y), (210, 210, 210))
>>>from PIL import ImageColor
>>> forx in range(100):
for y inrange(50, 100):
im.putpixel((x, y), ImageColor.getcolor('darkgray', 'RGBA'))
>>>im.getpixel((0, 0))
(210, 210, 210,255)
>>>im.getpixel((0, 50))
(169, 169, 169,255)
>>>im.save('putPixel.png')
3. 在图像上绘画
如果需要在图像上画线、矩形、圆形或其他简单形状,就用Pillow的ImageDraw模块。示例:
>>> from PIL import Image,ImageDraw
>>> im = Image.new('RGBA', (200,200), 'white')
>>> draw = ImageDraw.Draw(im)
1) 绘制形状
a) 点
point(xy, fill)方法绘制单个像素。xy 参数表示要画的点的列表。该列表可以是 x和 y 坐标的元组的列表,例如[(x, y), (x, y), ...],或是没有元组的 x 和 y 坐标的列表,例如[x1,y1, x2, y2, ...]。fill 参数是点的颜色,要么是一个 RGBA 元组,要么是颜色名称的字符串,如'red'。fill 参数是可选的。
b) 线
line(xy, fill,width)方法绘制一条线或一系列的线。xy 要么是一个元组的列表,例如[(x, y), (x, y), ...],要么是一个整数列表,例如[x1, y1,x2, y2, ...]。每个点都是正在绘制的线上的一个连接点。可选的 fill 参数是线的颜色,是一个 RGBA 元组或颜色名称。可选的 width 参数是线的宽度,如果未指定,缺省值为1。
c) 矩形
rectangle(xy,fill, outline)方法绘制一个矩形。xy 参数是一个矩形元组,形式为(left,top, right, bottom)。left 和 top 值指定了矩形左上角的x 和 y坐标,right 和bottom 指定了矩形的右下角。可选的 fill 参数是颜色,将填充该矩形的内部。可选的 outline 参数是矩形轮廓的颜色。
d) 椭圆
ellipse(xy, fill, outline)方法绘制一个椭圆。如果椭圆的宽度和高度一样,该方法将绘制一个圆。xy 参数是一个矩形元组(left, top, right, bottom),它表示正好包含该椭圆的
矩形。可选的fill 参数是椭圆内的颜色,可选的outline 参数是椭圆轮廓的颜色。
e) 多边形
polygon(xy,fill, outline)方法绘制任意的多边形。xy 参数是一个元组列表,例如[(x, y), (x, y), ...],或者是一个整数列表,例如[x1, y1,x2, y2, ...],表示多边形边的连接点。最后一对坐标将自动连接到第一对坐标。可选的 fill 参数是多边形内部的颜色,可选的 outline 参数是多边形轮廓的颜色。示例:
>>>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')
>>> fori in range(100, 200, 10):
draw.line([(i,0), (200, i - 100)], fill='green')
>>>im.save('drawing.png')
2) 绘制文本
ImageDraw 对象还有 text()方法,用于在图像上绘制文本。text()方法有 4 个参数:xy、text、fill 和 font。
• xy 参数是两个整数的元组,指定文本区域的左上角。
• text 参数是想写入的文本字符串。
• 可选参数 fill 是文本的颜色。
• 可选参数 font 是一个ImageFont 对象,用于设置文本的字体和大小。
>>> from PIL import Image,ImageDraw, ImageFont
>>> import os
>>> im = Image.new('RGBA', (200,200), 'white')
>>> draw = ImageDraw.Draw(im)
>>> 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)
>>> im.save('text.png')