小白都能看得懂的教程 看完这篇还不会生成随机验证码图片,你来打我!!!
小白都能看得懂的教程 一文教你实现生成随机图像验证码
大家好,我叫亓官劼(qí guān jié ),三本计算机在读,目前在积极准备21计算机考研中,同时也在学习后端开发,准备工作。不敢孤注一掷,因为要留条后路;不求两全其美在,因为那需要运气+机遇;只求学有所得,慢慢成长。CSDN中记录学习的点滴历程,时光荏苒,未来可期,加油~
博主博客文章内容导航(实时更新)
更多优质文章推荐:
- 收藏!最详细的Python全栈开发指南 看完这篇你还不会Python全栈开发 你来打我!!!
- 一本教你如何在前端实现富文本编辑器
- 小白都能看得懂的教程 一本教你如何在前端实现markdown编辑器
- 一文教会你Bootstrap,让你也可以快速建站
- 一文教你如何白嫖JetBrains全家桶(IDEA/PtChram/CLion)免费正版
- 小白都能看懂的实战教程 手把手教你Python Web全栈开发 (DAY 1)
- 小白都能看懂的实战教程 手把手教你Python Web全栈开发 (DAY 2)
- 小白都能看懂的实战教程 手把手教你Python Web全栈开发 (DAY 3)
- 小白都能看懂的实战教程 手把手教你Python Web全栈开发 (DAY 4)
- 小白都能看懂的实战教程 手把手教你Python Web全栈开发 (DAY 5)
- 小白都能看懂的实战教程 手把手教你Python Web全栈开发 (DAY 6)
- 小白都能看懂的实战教程 手把手教你Python Web全栈开发 (DAY 7)
**写在前面,文末附有完整源码,如果不想看的写的话,可以直接拿去使用!**本期小白都能看得懂的教程将会带领你实现我们的生成随机验证码的功能。这里演示的项目是我们之前教程中的(收藏!最详细的Python全栈开发指南 看完这篇你还不会Python全栈开发 你来打我!!!)没看过这个教程也无所谓,我们几乎不会使用项目中的东西,仅作为演示使用。
准备工作
好了,下面进入正题,我们来实现这个功能。首先这个是使用Python3进行开发的,我们需要用到一个PIL的库,这里安装库的pip3命令为:pip3 install pillow
。这里如果超时报错的话,我们可以使用cch
。
然后我们创建一个captcha.py
文件用来存放生成随机验证码的代码。这里面captcha
的意思是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写,也就是我们俗称的验证码。
这里我们将随机生成验证码的这个功能写成一个类Captcha,然后我们通过这个类的方法来生成随机图片验证码。使用类进行封装的话,可以对类内的部分私有方法进行封装,提高安全性。下面我们就来一步一步的实现生成随机验证码的各个功能。
本文原创为CSDN博主亓官劼,原文链接为:小白都能看得懂的教程 看完这篇还不会生成随机验证码图片,你来打我!!!,请大家认准原创。
我们本功能将会使用到3个库,我们先进行导入。
我们从PIL中导入Image,ImageDraw,ImageFont:
import random
import string
from PIL import Image,ImageDraw,ImageFont
# 这里面Image是PIL中的画布,ImageDraw是画笔,ImageFont是画笔的字体
设置我们类的一些基础参数
我们这里将生成随机验证码写成了一个Captcha类,下面我们来设置一些他的基础参数,我们一般需要设置的有图像验证码的宽、高,验证码位数、干扰线条数量、验证码大小、然后我们还需要构建一个验证码字符的源文件,这里各个部分在代码中进行了详细的注释,我们边看代码边看看注释!
import random
import string
from PIL import Image, ImageDraw, ImageFont
# 这里面Image是PIL中的画布,ImageDraw是画笔,ImageFont是画笔的字体
class Captcha(object):
# 生成随机验证码的位数,可以根据需要进行修改
number = 4
# 干扰线条的条数
line_number = 2
# 生成验证码图片的宽和高,可以根据需要进行修改
size = (100,40)
# 验证码字的大小,可以根据需要进行修改
fontsize = 24
# 建立验证码源文本
# list(string.ascii_letters) ASCII码中所有的字母
SOURCE = list(string.ascii_letters)
# 再加入'0'到'9'
for index in range(10):
SOURCE.append(str(index))
生成随机验证码文本
这里生成随机验证码的文本,我们只需要在SOURCE中随机的选取number个字符即可。
# 生成验证码文本
@classmethod
def __gene_random_captcha(cls,number):
# number为验证码位数,返回字符串
return ''.join(random.sample(cls.SOURCE,number))
生成随机字体
这里我们来实现生成随机字体的函数,因为同样的字,不同的字体,他的形状也是不一样的,所以这里我们的字体也是采用随机的。那么要生成随机的字体,那么首先我们就要先要有字体的文件。Windows下的字体文件路径为C/Windows/Fonts/
,MacBook下的字体文件路径为/System/Library/Fonts/
,如果找不到的话,可以看之前的一篇博文,内有详细的介绍:在Windows下和MacBook中如何查找本地的字体文件
在找到我们的字体文件之后,我们将它拖入到一个固定的文件夹,便于我们后面去获取这些字体文件。这里由于我这边是在之前OnlineForumPlatform项目中做的,所以这里将它放在了/static/font/文件夹下。
本文原创为CSDN博主亓官劼,原文链接为:小白都能看得懂的教程 看完这篇还不会生成随机验证码图片,你来打我!!!,请大家认准原创。
下面我们来实现我们的随机生成字体的函数。首先我们写一个fonts列表,存放所有我们有的字体的文件名称,这里大家根据自己的字体文件而定。代码为:
# 生成随机字体
@classmethod
def __generate_random_font(cls):
# 这里的fonts即是我们所有字体文件的名称,这里我是只复制过来了这么多,所以他的列表的这样,大家根据自己他字体文件来写这个fonts
fonts = [
'Palatino.ttc',
'PingFang.ttc',
'STHeiti Light.ttc',
'STHeiti Medium.ttc',
'Thonburi.ttc',
'Times.ttc'
]
font = random.choice(fonts)
# 这里前面的字符为我们字符文件的文件夹位置
return '/static/font/'+font
生成随机颜色
这里由于我们是使用RGBA来表示颜色,所以我们在各个颜色的值的范围为[0,255],我们这里可以设置默认的值为0和255,然后我们返回3种颜色的随机数值即可;
# 生成随机颜色
@classmethod
def __gene_random_color(cls,start=0,end=255):
# start为最小值,end为最大值,这里因为是RGB格式的,我们每个颜色的值最小为0,最大为255,所以这里默认为0和255
random.seed()
# 返回3种颜色的值
return (random.randint(start,end),random.randint(start,end),random.randint(start,end))
生成随机干扰线
绘制干扰线可以让我们的验证码不那么容易被软件轻松的破解,添加他的干扰项。
# 绘制干扰线
@classmethod
def __gene_line(cls,draw,width,height):
# 干扰性的开始位置和结束位置
begin = (random.randint(0,width),random.randint(0,height))
end = (random.randint(0,width),random.randint(0,height))
# 第一个参数为开始的位置和结束的位置,第二个参数的线的颜色,第三个参数为宽度
draw.line([begin,end],fill = cls.__gene_random_color(0,255),width=2)
生成随机干扰点
绘制干扰点可以让我们的验证码不那么容易被软件轻松的破解,添加他的干扰项。
# 绘制干扰点
@classmethod
def __gene_points(cls,draw,ponit_chance,width,height):
# chance为界限,如果当前随机数大于他,则绘制一个干扰电
chance = min(100,max(0,int(ponit_chance)))
# 遍历图
for i in range(height):
for j in range(width):
temp = random.randint(0,100)
if temp > chance:
# 绘制干扰点,第一个参数为位置,第二个参数为颜色
draw.point((j,i),fill = cls.__gene_random_color(0,255))
生成随机图片验证码
在完成各个功能函数之后,最后我们来实现我们生成随机图片验证码的函数。这里我们边看代码边解释各个的原理,在代码中进行了非常详细的一个注释说明。
本文原创为CSDN博主亓官劼,原文链接为:小白都能看得懂的教程 看完这篇还不会生成随机验证码图片,你来打我!!!,请大家认准原创。
# 生成图片验证码
@classmethod
def generate_graph_captcha(cls):
# 验证码图片的宽和高,这里的size是我们上面进行设置的宽和高
width,height = cls.size
# 创建一个画布
# 第一个参数为颜色的类型RGBA型,第二个参数为宽和高,第三个参数为颜色的值,这里调用__gene_random_color,这里我们参数颜色值可以自己进行修改
image = Image.new('RGBA',(width,height),cls.__gene_random_color(0,100))
# 设置验证码的字体
# 第一个参数为字体的值,即我们使用什么字体,我们调用生成随机字体的函数。第二个参数为字体大小,在上面我们设置了默认值,可以进行修改
font = ImageFont.truetype(cls.__generate_random_font(),cls.fontsize)
# 创建画笔,并且绑定到上面创建的画布image上
draw = ImageDraw.Draw(image)
# 生成随机验证码文本,参数为验证码位数
captcha_str = cls.__gene_random_captcha(cls.number)
# 获取字体的尺寸
font_width,font_height = font.getsize(captcha_str)
# 设置我们绘制的位置,这里为了验证码尽量在中间,我们选择了中间点,大家可以根据需要进行修改
position = ((width - font_width)/2, (height - font_height)/2)
# 填充字符串
# 第一个参数为绘制的位置,第二个参数为文本,这里使用生成的验证码文本,第三个参数为字体,第四个参数为文字的颜色
draw.text(position, captcha_str,font = font,fill = cls.__gene_random_color(150,255))
# 绘制干扰性
for i in range(cls.line_number):
cls.__gene_line(draw,width,height)
# 绘制干扰点
cls.__gene_points(draw,90,width,height)
# open的第一个参数的文件名称,在这里也可以在前面加上文件夹的名,例如/static/captcha.png,第二个参数为打开方式
with open('captcha.png','wb') as fp:
image.save(fp)
return (captcha_str,image)
调用方法,生成随机验证码
到这里我们的功能已经完全的实现啦,然后我们只需要创建我们的对象,然后调用方法Captcha.generate_graph_captcha()
即可在指定的位置生成我们的验证码图像。
全部源码
最后就是我们本功能的全部源码啦,如果不想码代码的话,可以直接拿过去用哦!
import random
import string
from PIL import Image, ImageDraw, ImageFont
# 这里面Image是PIL中的画布,ImageDraw是画笔,ImageFont是画笔的字体
class Captcha(object):
# 生成随机验证码的位数,可以根据需要进行修改
number = 4
# 干扰线条的条数
line_number = 2
# 生成验证码图片的宽和高,可以根据需要进行修改
size = (100,40)
# 验证码字的大小,可以根据需要进行修改
fontsize = 24
# 建立验证码源文本
# list(string.ascii_letters) ASCII码中所有的字母
SOURCE = list(string.ascii_letters)
# 再加入'0'到'9'
for index in range(10):
SOURCE.append(str(index))
# 绘制干扰线
@classmethod
def __gene_line(cls,draw,width,height):
# 干扰性的开始位置和结束位置
begin = (random.randint(0,width),random.randint(0,height))
end = (random.randint(0,width),random.randint(0,height))
# 第一个参数为开始的位置和结束的位置,第二个参数的线的颜色,第三个参数为宽度
draw.line([begin,end],fill = cls.__gene_random_color(0,255),width=2)
# 绘制干扰点
@classmethod
def __gene_points(cls,draw,ponit_chance,width,height):
# chance为界限,如果当前随机数大于他,则绘制一个干扰电
chance = min(100,max(0,int(ponit_chance)))
# 遍历图
for i in range(height):
for j in range(width):
temp = random.randint(0,100)
if temp > chance:# 绘制干扰点,第一个参数为位置,第二个参数为颜色draw.point((j,i),fill = cls.__gene_random_color(0,255))
# 生成验证码文本
@classmethod
def __gene_random_captcha(cls,number):
# number为验证码位数,返回字符串
return ''.join(random.sample(cls.SOURCE,number))
# 生成随机字体
@classmethod
def __generate_random_font(cls):
# 这里的fonts即是我们所有字体文件的名称,这里我是只复制过来了这么多,所以他的列表的这样,大家根据自己他字体文件来写这个fonts
fonts = [
'Palatino.ttc',
'PingFang.ttc',
'STHeiti Light.ttc',
'STHeiti Medium.ttc',
'Thonburi.ttc',
'Times.ttc'
]
font = random.choice(fonts)
# 这里前面的字符为我们字符文件的文件夹位置
return '/static/font/'+font
# 生成随机颜色
@classmethod
def __gene_random_color(cls,start=0,end=255):
# start为最小值,end为最大值,这里因为是RGB格式的,我们每个颜色的值最小为0,最大为255,所以这里默认为0和255
random.seed()
# 返回3种颜色的值
return (random.randint(start,end),random.randint(start,end),random.randint(start,end))
# 生成图片验证码
@classmethod
def generate_graph_captcha(cls):
# 验证码图片的宽和高,这里的size是我们上面进行设置的宽和高
width,height = cls.size
# 创建一个画布
# 第一个参数为颜色的类型RGBA型,第二个参数为宽和高,第三个参数为颜色的值,这里调用__gene_random_color,这里我们参数颜色值可以自己进行修改
image = Image.new('RGBA',(width,height),cls.__gene_random_color(0,100))
# 设置验证码的字体
# 第一个参数为字体的值,即我们使用什么字体,我们调用生成随机字体的函数。第二个参数为字体大小,在上面我们设置了默认值,可以进行修改
font = ImageFont.truetype(cls.__generate_random_font(),cls.fontsize)
# 创建画笔,并且绑定到上面创建的画布image上
draw = ImageDraw.Draw(image)
# 生成随机验证码文本,参数为验证码位数
captcha_str = cls.__gene_random_captcha(cls.number)
# 获取字体的尺寸
font_width,font_height = font.getsize(captcha_str)
# 设置我们绘制的位置,这里为了验证码尽量在中间,我们选择了中间点,大家可以根据需要进行修改
position = ((width - font_width)/2, (height - font_height)/2)
# 填充字符串
# 第一个参数为绘制的位置,第二个参数为文本,这里使用生成的验证码文本,第三个参数为字体,第四个参数为文字的颜色
draw.text(position, captcha_str,font = font,fill = cls.__gene_random_color(150,255))
# 绘制干扰性
for i in range(cls.line_number):
cls.__gene_line(draw,width,height)
# 绘制干扰点
cls.__gene_points(draw,90,width,height)
# open的第一个参数的文件名称,在这里也可以在前面加上文件夹的名,例如/static/captcha.png,第二个参数为打开方式
with open('captcha.png','wb') as fp:
image.save(fp)
return (captcha_str,image)
Captcha.generate_graph_captcha()