Python:生成验证码图片

class ImageCode:
    # 通过数字获取ascii表中的对应字母
    @staticmethod
    def get_char(length):
        sources = "0123xcrfvbgtyhn456zjumi789qweasdklopQAZXSWEDCFVRTGYBHNJUMIKOLP"
        data = ""
        for i in range(length):
            # random.randint(begin, end) 返回begin<= i <=end 左闭右闭区间
            data += sources[random.randint(0, 61)]
        return data
        # return chr(random.randint(65, 90))

    # 获取随机颜色
    @staticmethod
    def get_color(*args):
        if args == ():
            return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)
        while True:
            text_color = ImageCode.get_color()
            aberration = 3 * (text_color[0] - args[0][0]) ** 2 + 4 * (text_color[0] - args[0][1]) ** 2 + 2 * (
                    text_color[0] - args[0][2]) ** 2
            # 设置字体颜色与背景色差,值越大,字体越清晰,机器人就更容易识别,相对应的代价就是需要随机更多次的RGB值。
            # 极端情况验证码字体背景rgb均为128,aberration最小的最大值为147456
            rgb2 = 100000
            if aberration > rgb2:
                return text_color

    @staticmethod
    def get_img(char_code_length):
        """
        获取验证码图片
        :param char_code_length: 验证码长度
        :return:
        """
        # 创建图片对象
        img_back = ImageCode.get_color()
        img_width = 120
        img_height = 50
        img = Image.new(mode='RGB', size=(img_width, img_height), color=img_back)
        # 创建画笔对象
        draw = ImageDraw.Draw(img, mode='RGB')
        # 噪点 xy:基于图片的坐标,fill表示点颜色
        for i in range(100):
            draw.point([random.randint(0, img_width), random.randint(0, img_height)], fill=ImageCode.get_color())

        # 噪线 xy:(起点坐标,终点坐标) fill:颜色  width:线宽
        # draw.line((50, 30, 100, 60),fill='purple', width=5)
        for i in range(20):
            draw.line([random.randint(0, img_width), random.randint(0, img_height), random.randint(0, img_width),
                       random.randint(0, img_height)],
                      fill=ImageCode.get_color())
        # 划圆或弧线
        for i in range(30):
            x = random.randint(0, img_width)
            y = random.randint(0, img_height)
            x2 = x + 4
            y2 = y + 4

            draw.arc((x, y, x2, y2), 0, 90, fill=ImageCode.get_color())
        from MR_ERP import settings
        path = os.path.join(settings.BASE_DIR, "static", "fonts", "setofont.ttf")
        font = ImageFont.truetype(path, 30)

        # 用来拼接验证码字符的
        char_code = ImageCode.get_char(char_code_length)
        for i in range(char_code_length):
            char = char_code[i]
            height = random.randint(10, 15)
            draw.text([18 * (i + 1), height], char, ImageCode.get_color(img_back), font=font)

        # 模糊效果和边缘增强效果
        # img = img.filter(ImageFilter.BLUR)
        # img = img.filter(ImageFilter.EDGE_ENHANCE_MORE)
        # img.show()
        # print(char_code)
        return img, char_code

返回图片给前端:

class GeneralAuthCode(APIView):
    """
    get: 获取验证码
    """
    @staticmethod
    def get(request):
        try:
            img, char_code = ImageCode.get_img(4)
            key = str(idCreatorUtil.appKeyWorker.get_id())
            # 保存验证码到redis
            authCodeUtil.create_auth_code(key, char_code)
            buf = io.BytesIO()
            img.save(buf, "png")

            result_dict = {
                "img_code": 'data:image/png;base64,' + base64.b64encode(buf.getvalue()).decode(),
                "key": key
            }
            buf.close()
            return resultUtil.result(status=200, msg="success", data=result_dict)
            # 前端直接显示图片
            # data = buf.getvalue()
            # buf.close()
            # return HttpResponse(data, content_type="image/jpeg")
        except Exception:
            traceback.print_exc()
            return resultUtil.error_500_result()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值