随着互联网行业的迅速发展,网络安全问题不可忽视。为了保障用户账号的安全性,很多应用软件和网站都引入了验证码机制。验证码通常用于应用软件和网站登录、注册或其他需要用户验证的场合,可以有效防止恶意攻击和自动化脚本的滥用。本节教程将介绍如何使用PIL(Pillow)库来生成随机图片验证码,提高网络的安全性。
验证码效果图如下所示:
制作图片验证码
(1)准备工作
在生成随机图片验证码之前,我们需要准备一些必要的库。首先,确保要安装PIL第三方库,如果还没有安装,可以通过pip进行安装:
pip install Pillow
(2)导入必要的库并配置验证码参数
import random, string
from PIL import Image, ImageDraw, ImageFont, ImageFilter
import os
# 配置验证码参数
font_type = "simhei.ttf" # 配置验证码字体,这里为“黑体”
number = 6 # 生成6位数的验证码
code_size =(110, 50) # 生成验证码的图像大小
bg_color = "#FFFFFF" # 设置背景色(这里为白色)
add_line = True # 是否要加干扰线和干扰点
# 生成的验证码保存位置
# 注意不能写为“.jpg”后缀名,因为jpg格式不支持RGBA模式
output_path = "D:\\vcode.png"
(3)生成随机字符串
验证码图片必须有字母和数字,所以需要生成一个随机字符串,包含26个字母和0~9的十个数字。
# 随机生成一个字符串
def create_text():
# 利用string模块的ascii_letters属性生成26个英文字母,并保存到列表中
data = list(string.ascii_letters)
# 遍历10次,把0~9十个数字追加到data列表里
for index in range(0,10):
data.append(str(index))
# 返回data列表中的一个随机数
return "".join(random.sample(data, 1))
(4)添加随机的干扰线和干扰点
# 添加干扰线,生成5~9条干扰线
def create_lines(drawing,width,height):
for i in range(random.randint(5,9)):
# 随机生成干扰线颜色
linecolor = (random.randint(0,255),random.randint(0,255),random.randint(0,255))
# 随机位置生成干扰线
start = (random.randint(0,width),random.randint(0,height))
end = (random.randint(0,width),random.randint(0,height))
drawing.line([start,end],fill = linecolor)
#添加干扰点,生成30个干扰点
def create_points(drawing,width,height):
for i in range(30):
# 随机生成干扰点颜色
pointcolor = (random.randint(0,255),random.randint(0,255),random.randint(0,255))
# 随机位置生成干扰点
start = (random.randint(0,width),random.randint(0,height))
end = (random.randint(0,width),random.randint(0,height))
drawing.point([start,end],fill = pointcolor)
(5)生成验证码图片的函数
def create_code():
# 设置验证码的初始横轴和纵轴偏移量
x_begin, y_begin = 2, 0
# 验证码的宽度和高度
width, height = code_size
# 创建验证码背景图片
image = Image.new("RGBA",(width,height),bg_color)
# 设置验证码的字体和大小
font = ImageFont.truetype(font_type,25)
# 创建一个可以在图像上绘制的对象
drawing = ImageDraw.Draw(image)
# 遍历6次生成6个验证码
for i in range(number):
# 随机生成验证码的字体颜色
font_color = (random.randint(0,255),random.randint(0,255),random.randint(0,255))
# 随机生成一个验证码字母或数字
text = create_text()
# 验证码随机出现在横轴和纵轴的坐标位置
x = x_begin + i * int(width / (number))
y = random.randint(y_begin, int(height / 2))
drawing.text((x, y), text = text, font = font, fill = font_color)
if add_line:
create_lines(drawing,width,height)
create_points(drawing,width,height)
# 保存验证码到D盘,名为vcode.png
image.save(output_path)
# windows下打开文件
os.startfile(output_path)
制作图片验证码的完整代码如下所示:
动手练一练:
import random, string
from PIL import Image, ImageDraw, ImageFont, ImageFilter
import os
# 配置验证码参数
font_type = "simhei.ttf" # 配置验证码字体,这里为“黑体”
number = 6 # 生成6位数的验证码
code_size =(110, 50) # 生成验证码的图像大小
bg_color = "#FFFFFF" # 设置背景色(这里为白色)
add_line = True # 是否要加干扰线和干扰点
# 生成的验证码保存位置
# 注意不能写为“.jpg”后缀名,因为jpg格式不支持RGBA模式
output_path = "D:\\vcode.png"
# 随机生成一个字符串
def create_text():
# 利用string模块的ascii_letters属性生成26个英文字母,并保存到列表中
data = list(string.ascii_letters)
# 遍历10次,把0~9十个数字追加到data列表里
for index in range(0,10):
data.append(str(index))
# 返回data列表中的一个随机数
return "".join(random.sample(data, 1))
# 添加干扰线,生成5~9条干扰线
def create_lines(drawing,width,height):
for i in range(random.randint(5,9)):
# 随机生成干扰线颜色
linecolor = (random.randint(0,255),random.randint(0,255),random.randint(0,255))
# 随机位置生成干扰线
start = (random.randint(0,width),random.randint(0,height))
end = (random.randint(0,width),random.randint(0,height))
drawing.line([start,end],fill = linecolor)
# 添加干扰点,生成30个干扰点
def create_points(drawing,width,height):
for i in range(30):
# 随机生成干扰点颜色
pointcolor = (random.randint(0,255),random.randint(0,255),random.randint(0,255))
# 随机位置生成干扰点
start = (random.randint(0,width),random.randint(0,height))
end = (random.randint(0,width),random.randint(0,height))
drawing.point([start,end],fill = pointcolor)
# 生成验证码的函数
def create_code():
# 设置验证码的初始横轴和纵轴偏移量
x_begin, y_begin = 2, 0
# 验证码的宽度和高度
width, height = code_size
# 创建验证码背景图片
image = Image.new("RGBA",(width,height),bg_color)
# 设置验证码的字体和大小
font = ImageFont.truetype(font_type,25)
# 创建一个可以在图像上绘制的对象
drawing = ImageDraw.Draw(image)
# 遍历6次生成6个验证码
for i in range(number):
# 随机生成验证码的字体颜色
font_color = (random.randint(0,255),random.randint(0,255),random.randint(0,255))
# 随机生成一个验证码字母或数字
text = create_text()
# 验证码随机出现在横轴和纵轴的坐标位置
x = x_begin + i * int(width / (number))
y = random.randint(y_begin, int(height / 2))
drawing.text((x, y), text = text, font = font, fill = font_color)
if add_line:
create_lines(drawing,width,height)
create_points(drawing,width,height)
# 保存验证码到D盘,名为vcode.png
image.save(output_path)
# windows下打开文件
os.startfile(output_path)
# 当前模块直接被执行
if __name__ == "__main__":
create_code()