python学习:图片验证码

图片验证码

        生成图片验证码,使用到pillow组件。使用pip3 install pillow命令进行安装。

示例:

创建一个html页面,login.html

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>登陆验证码</title>

    <script>

        //点击图片再次更新src,再次发送请求

        function change(ths){

            ths.src = ths.src + "?";

        }

    </script>

</head>

<body>

    <form>

        <p>用户:<input type="text" name="user"></p>

        <p>密码:<input type="password" name="pwd"></p>

        <p>验证码:<input type="text" name="code"></p>

        <!--img的src获取图片,会发送一次请求

                    如果是静态地址,Django自己发送请求,读取statics目录下图片

                    如果是url地址,我们可以自己读取目录下图片,使用HttpResponse返回图片字符串

                -->

        <p><img src="/code" onclick="change(this)"></p>

        <p><input type="submit" value="提交"></p>

    </form>

</body>

</html>

 

 修改urls.py,创建url

一个是图片验证码请求路径,一个是login页面路径

path('code/',views.code),

path("login/",views.login),

 

修改views.py,创建对应的视图函数

#创建验证码

def code(request):

    # #读取静态图片,返回作为验证码

    ##打开文件

    # f = open("statics/pic1.jpg","rb")

    # data = f.read()

    # return HttpResponse(data)

 

    #创建BytesIO对象

    stream = BytesIO()

    #获取图片,验证码字符串

    img,code =verification_code.get_code_img()

    #将图片保存到内存

    img.save(stream,"JPEG")

    #将内存图片返回

    return HttpResponse(stream.getvalue())

#返回登陆页面

def login(request):

    return render(request,"login.html")

 

创建utils包,创建verification_code.py文件,使用pillow模块绘制验证码图片,返回对应验证码和图片

import random

from PIL import Image,ImageDraw,ImageFont

 

#获取图片操作

def getImage():

    #获取图片对象

    img = Image.open("statics/pic1.jpg")

    #图片尺寸

    w,h = img.size

 

    #图片缩放

    img.thumbnail(w//2,h//2)

    #保存为新图片

    img.save("statics/myimg.jpg","jpg")

 

'''

验证码字符集

'''

def get_chars_str():

    _letter_cases = "abcdefghjkmnpqrstuvwxy"  # 小写字母,去除可能干扰的i,l,o,z

    _upper_cases = _letter_cases.upper()  # 大写字母

    _numbers = ''.join(map(str, range(3, 10)))  # 数字

    init_chars = ''.join((_letter_cases, _upper_cases, _numbers))

    return init_chars

 

#获取RGB三位颜色值

def get_random_color():

    c1 = random.randint(0,255)

    c2 = random.randint(0,255)

    c3 = random.randint(0,255)

    return (c1,c2,c3)

 

#指定字符串中获取随机字符,传入字符串

def get_random_char(chars):

    random_char = random.choice(chars)

    return random_char

 

#获取指定长度随机字符串

def get_random_str(length = 4):

    str = ''

    #如果传入长度为0

    if length == 0:

        length = 4

    while length > 0:

        str = str + get_random_char(get_chars_str())

        length = length-1

    return  str

 

"""

 生成验证码图片

 :param mode:模式

 :param width:宽

 :param heigth:高

 :param font 字体

 :param font_size 字体大小

 :param line 是否有画线,默认True

 :param line_count 线数量

 :param dot 是否画点,默认True

 :param dot_count 点数量

:return: [0]: PIL Image实例

:return: [1]: 验证码图片中的字符串

"""

def get_code_img(

        mode="RGB",

        width = 120,

        height = 40,

        font = "simsun.ttc",

        font_size = 30,

        line = True,

        line_count = 5,

        dot = True,

        dot_count = 30,

        back_color = (122,122,122)

):

    #获取image对象

    #参数1:mode,模式RGB

    #参数2:宽,高,(width,height)

    #参数3:颜色

    image = Image.new(mode,(width,height),back_color)

    #获取画笔draw对象

    draw = ImageDraw.Draw(image)

    #获取字体对象

    #设置字体大小size=10

    font = ImageFont.truetype(font,size=font_size)

 

    #获取code

    code = get_random_str()

    code_len = len(code)

    for c in code:

        #绘制字符

        #参数1:(x,y)位置元组

        #参数2:字符

        #参数3:颜色

        #参数4:字体

        draw.text(((width-code_len*font_size),1),c,get_random_color(),font)

        code_len = code_len-1

    #是否需要画线

    if  line :

        for i in range(0,line_count):

            #生成坐标

            x1 = random.randint(0,width)

            y1 = random.randint(0,height)

            x2 = random.randint(0,width)

            y2 = random.randint(0,height)

            #画线draw.line()

            #参数1:坐标元组

            #参数2:fill()填充颜色

            draw.line((x1,x2,y1,y2),fill=get_random_color())

    #是否需要画点

    if dot:

        for i in range(0,dot_count):

            x1 = random.randint(0, width)

            y1 = random.randint(0, height)

            draw.point((x1,y1),fill=get_random_color())

    return image,code

 

posted @ 2021-01-07 20:31  渔歌晚唱  阅读(221)  评论(0)    收藏  举报