一、Pillow
PIL:Python Imaging Library,已经是Python平台事实上的图像处理标准库了。PIL功能非常强大,但API却非常简单易用。
由于PIL仅支持到Python 2.7,加上年久失修,于是一群志愿者在PIL的基础上创建了兼容的版本,名字叫Pillow,支持最新Python 3.x,又加入了许多新特性,因此,我们可以直接安装使用Pillow。
安装Pillow
如果安装了Anaconda,Pillow就已经可用了。否则,需要在命令行下通过pip安装:
$ pip install pillow
如果遇到Permission denied安装失败,请加上sudo重试。
操作图像
来看看最常见的图像缩放操作,只需三四行代码:
from PIL import Image
# 打开一个jpg图像文件,注意是当前路径: im = Image.open('test.jpg') # 获得图像尺寸: w, h = im.size print('Original image size: %sx%s' % (w, h)) # 缩放到50%: im.thumbnail((w//2, h//2)) print('Resize image to: %sx%s' % (w//2, h//2)) # 把缩放后的图像用jpeg格式保存: im.save('thumbnail.jpg', 'jpeg')
其他功能如切片、旋转、滤镜、输出文字、调色板等一应俱全。
比如,模糊效果也只需几行代码:
from PIL import Image, ImageFilter
# 打开一个jpg图像文件,注意是当前路径: im = Image.open('test.jpg') # 应用模糊滤镜: im2 = im.filter(ImageFilter.BLUR) im2.save('blur.jpg', 'jpeg')
效果如下:
PIL的ImageDraw提供了一系列绘图方法,让我们可以直接绘图。比如要生成字母验证码图片:
from PIL import Image, ImageDraw, ImageFont, ImageFilter
import random
# 随机字母: def rndChar(): return chr(random.randint(65, 90))
# 随机颜色1: def rndColor(): return (random.randint(64, 255), random.randint(64, 255), random.randint(64, 255))
# 随机颜色2: def rndColor2(): return (random.randint(32, 127), random.randint(32, 127), random.randint(32, 127))
# 240 x 60: width = 60 * 4 height = 60 image = Image.new('RGB', (width, height), (255, 255, 255)) # 创建Font对象: font = ImageFont.truetype('Arial.ttf', 36) # 创建Draw对象: draw = ImageDraw.Draw(image) # 填充每个像素: for x in range(width): for y in range(height): draw.point((x, y), fill=rndColor()) # 输出文字: for t in range(4): draw.text((60 * t + 10, 10), rndChar(), font=font, fill=rndColor2()) # 模糊: image = image.filter(ImageFilter.BLUR) image.save('code.jpg', 'jpeg')
我们用随机颜色填充背景,再画上文字,最后对图像进行模糊,得到验证码图片如下:
如果运行的时候报错:
IOError: cannot open resource
这是因为PIL无法定位到字体文件的位置,可以根据操作系统提供绝对路径,比如:
'/Library/Fonts/Arial.ttf'
要详细了解PIL的强大功能,请请参考Pillow官方文档:
Pillow (PIL Fork) 9.2.0 documentation
总结:
PIL提供了操作图像的强大功能,可以通过简单的代码完成复杂的图像处理。
二、海龟绘图
在1966年,Seymour Papert和Wally Feurzig发明了一种专门给儿童学习编程的语言——LOGO语言,它的特色就是通过编程指挥一个小海龟(turtle)在屏幕上绘图。
海龟绘图(Turtle Graphics)后来被移植到各种高级语言中,Python内置了turtle库,基本上100%复制了原始的Turtle Graphics的所有功能。
我们来看一个指挥小海龟绘制一个长方形的简单代码:
# 导入turtle包的所有内容: from turtle import *
# 设置笔刷宽度: width(4)
# 前进: forward(200) # 右转90度: right(90)
# 笔刷颜色: pencolor('red') forward(100) right(90)
pencolor('green') forward(200) right(90)
pencolor('blue') forward(100) right(90)
# 调用done()使得窗口等待被关闭,否则将立刻关闭窗口: done()
在命令行运行上述代码,会自动弹出一个绘图窗口,然后绘制出一个长方形:
从程序代码可以看出,海龟绘图就是指挥海龟前进、转向,海龟移动的轨迹就是绘制的线条。要绘制一个长方形,只需要让海龟前进、右转90度,反复4次。
调用width()函数可以设置笔刷宽度,调用pencolor()函数可以设置颜色。更多操作请参考turtle库的说明。
绘图完成后,记得调用done()函数,让窗口进入消息循环,等待被关闭。否则,由于Python进程会立刻结束,将导致窗口被立刻关闭。
turtle包本身只是一个绘图库,但是配合Python代码,就可以绘制各种复杂的图形。例如,通过循环绘制5个五角星:
from turtle import *
def drawStar(x, y): pu() goto(x, y) pd() # set heading: 0 seth(0) for i in range(5): fd(40) rt(144)
for x in range(0, 250, 50): drawStar(x, 0)
done()
程序执行效果如下:
使用递归,可以绘制出非常复杂的图形。例如,下面的代码可以绘制一棵分型树:
from turtle import *
# 设置色彩模式是RGB: colormode(255)
lt(90)
lv = 14 l = 120 s = 45
width(lv)
# 初始化RGB颜色: r = 0 g = 0 b = 0 pencolor(r, g, b)
penup() bk(l) pendown() fd(l)
def draw_tree(l, level): global r, g, b # save the current pen width w = width()
# narrow the pen width width(w * 3.0 / 4.0) # set color: r = r + 1 g = g + 2 b = b + 3 pencolor(r % 200, g % 200, b % 200)
l = 3.0 / 4.0 * l
lt(s) fd(l)
if level < lv: draw_tree(l, level + 1) bk(l) rt(2 * s) fd(l)
if level < lv: draw_tree(l, level + 1) bk(l) lt(s)
# restore the previous pen width width(w)
speed("fastest")
draw_tree(l, 4)
done()
执行上述程序需要花费一定的时间,最后的效果如下:
神龙|纯净稳定代理IP免费测试>>>>>>>>天启|企业级代理IP免费测试>>>>>>>>IPIPGO|全球住宅代理IP免费测试