一百一十三:CMS系统之图形验证码生成

爷,独闯天下 提交于 2019-12-05 18:10:42

 

安装Pillow库,用于生成图形验证码:pip install Pillow

字体文件来源

生成一个验证码图片

import randomimport stringfrom PIL import Image, ImageDraw, ImageFont# Image:一个画布# ImageDraw:一个画笔# ImageFont:画笔的字体class Captcha(object):    """ 生成图形验证码 """    number = 4  # 生成几位数的验证码    size = (100, 30)  # 验证码图片的宽度和高度    fontsize = 25  # 验证码字体大小    line_number = 2  # 加入干扰线的条数    # 构建一个验证码源文本    SOURCE = list(string.ascii_letters)    for index in range(0, 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(), width=2)    # 用来绘制干扰点    @classmethod    def __gene_points(cls, draw, point_chance, width, height):        chance = min(100, max(0, int(point_chance)))  # 大小限制在[0, 100]        for w in range(width):            for h in range(height):                tmp = random.randint(0, 100)                if tmp > 100 - chance:                    draw.point((w, h), fill=cls.__gene_random_color())    # 生成随机的颜色    @classmethod    def __gene_random_color(cls, start=0, end=255):        random.seed()        return (random.randint(start, end), random.randint(start, end), random.randint(start, end))    # 随机选择一个字体    @classmethod    def __gene_random_font(cls):        fonts = [            'Courgette-Regular.ttf',            'LHANDW.TTF',            'Lobster-Regular.ttf',            'verdana.ttf'        ]        font = random.choice(fonts)        return 'utils/captcha/' + font  # 返回字体路径    # 用来随机生成一个字符串(包括英文和数字)    @classmethod    def gene_text(cls, number):  # number是生成验证码的位数        return ''.join(random.sample(cls.SOURCE, number))    # 生成验证码    @classmethod    def gene_graph_captcha(cls):        width, height = cls.size  # 验证码图片的宽和高        # 创建图片        # R:Red(红色)0-255        # G:G(绿色)0-255        # B:B(蓝色)0-255        # A:Alpha(透明度)        image = Image.new('RGBA', (width, height), cls.__gene_random_color(0, 100))        font = ImageFont.truetype(cls.__gene_random_font(), cls.fontsize)  # 验证码的字体        draw = ImageDraw.Draw(image)  # 创建画笔        text = cls.gene_text(cls.number)  # 生成字符串        font_width, font_height = font.getsize(text)  # 获取字体的尺寸        # 填充字符串        draw.text(((width - font_width) / 2, (height - font_height) / 2), text, font=font,                  fill=cls.__gene_random_color(150, 255))        # 绘制干扰线        for x in range(0, cls.line_number):            cls.__gene_line(draw, width, height)        cls.__gene_points(draw, 10, width, height)  # 绘制噪点        # 保存到本地        with open('captcha.png', 'wb') as fp:            image.save(fp)        return (text, image)if __name__ == '__main__':    Captcha.gene_graph_captcha()

写一个获取验证码的视图给前端调用

from io import BytesIOfrom flask import Blueprint, views, render_template, make_responsefrom utils.captcha import Captchabp = Blueprint("front", __name__)@bp.route('/captcha/')def graph_captcha():    """ 获取验证码 """    text, image = Captcha.gene_graph_captcha()    out = BytesIO()  # 二进制流    image.save(out, 'png')    out.seek(0)    resp = make_response(out.read())  # 二进制流读取出来放到响应对象中    resp.content_type = 'image/png'    return resp

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!