生成网页随机验证码

使用方法
captcha = Captcha()
text, response_img = captcha.code_response()

直接用就行

# coding: utf-8
# +-------------------------------------------------------------------
# | Project     : Lost_track_of_time
# | Author      : 今夕何夕
# | QQ/Email    : 184566608<qingyueheji@qq.com>
# | Time        : 2017-07-03 17:12
# | Describe    : 生成网页随机验证码
# +-------------------------------------------------------------------
import random
from io import BytesIO

from PIL import Image, ImageDraw, ImageFont
import time
import os
import string

from django.http import HttpResponse

# pip install Pillow
# Image:是一个画板(context),ImageDraw:是一个画笔, ImageFont:画笔的字体

# Captcha验证码
class Captcha:
    def __init__(self, number: int = 4):
        # 把一些常量抽取成类属性
        # 字体的位置
        self._font_path = os.path.join(os.path.dirname(__file__), ‘verdana.ttf‘)
        # font_path = ‘font.ttf‘
        # 生成几位数的验证码
        self._number = number
        # 生成验证码图片的宽度和高度
        self._size = (100, 36)
        # 背景颜色,默认为白色 RGB(Re,Green,Blue)
        self._bgcolor = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
        # 随机字体颜色
        random.seed(int(time.time()))
        self._fontcolor = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
        # 验证码字体大小
        self._fontsize = 25
        # 随机干扰线颜色。
        self._linecolor = (random.randint(0, 250), random.randint(0, 255), random.randint(0, 250))
        # 是否要加入干扰线
        self._draw_line = True
        # 是否绘制干扰点
        self._draw_point = True
        # 加入干扰线的条数
        self._line_number = random.randint(3, 8)

        self._source = list(string.ascii_letters)
        for index in range(0, 10):
            self._source.append(str(index))

    # 用来随机生成一个字符串(包括英文和数字)
    # 定义成类方法,然后是私有的,对象在外面不能直接调用
    def _gene_text(self):
        return ‘‘.join(random.sample(self._source, self._number))  # number是生成验证码的位数

    # 用来绘制干扰线
    def _gene_line(self, 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=self._linecolor)

    # 用来绘制干扰点
    def _gene_points(self, 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=(0, 0, 0))

    # 生成验证码
    def gene_code(self):
        width, height = self._size  # 宽和高
        image = Image.new(‘RGBA‘, (width, height), self._bgcolor)  # 创建画板
        font = ImageFont.truetype(self._font_path, self._fontsize)  # 验证码的字体
        draw = ImageDraw.Draw(image)  # 创建画笔
        text = self._gene_text()  # 生成字符串
        font_width, font_height = font.getsize(text)
        draw.text(((width - font_width) / 2, (height - font_height) / 2), text, font=font, fill=self._fontcolor)  # 填充字符串
        # 如果需要绘制干扰线
        if self._draw_line:
            # 遍历line_number次,就是画line_number根线条
            for x in range(0, self._line_number):
                self._gene_line(draw, width, height)
        # 如果需要绘制噪点
        if self._draw_point:
            self._gene_points(draw, 10, width, height)

        return text, image

    def code_response(self):
        text, image = self.gene_code()
        # BytesIO:相当于一个管道,用来存储图片的流数据
        out = BytesIO()
        # 调用image的save方法,将这个image对象保存到BytesIO中
        image.save(out, ‘png‘)
        # 将BytesIO的文件指针移动到最开始的位置
        out.seek(0)

        response = HttpResponse(content_type=‘image/png‘)
        # 从BytesIO的管道中,读取出图片数据,保存到response对象上
        response.write(out.read())
        response[‘Content-length‘] = out.tell()

        return text, response

生成网页随机验证码

上一篇:HTML基础(列表)


下一篇:前端动画lottie-web