zoukankan      html  css  js  c++  java
  • python3 实现基础图形验证码

    每日一句

    When it rains , look for rainbows.When it’s dark,look for stars.

    生成随机图片验证码,可参考如下代码1所示:

    import random
    from io import BytesIO
    from PIL import Image, ImageDraw, ImageFont, ImageFilter
    # pip install pillow
    
    class VerifyCode():
    
        def __init__(self):
            self._letter_cases = 'abcdefghjkmnpqrstuvwxy'
            self._upper_cases = self._letter_cases.upper()
            self._numbers = ''.join(map(str, range(3, 10)))
            pass
    
        # 需要把monaco.ttf放到此程序目录下,下载地址https://github.com/todylu/monaco.ttf
    
        def createCodeImage(self, size=(120, 30), img_type='jpg',
                            mode='RGB', bg_color=(255, 255, 255), fg_color=(0, 0, 255),
                            font_size=18, font_type='./Monaco.ttf',
                            length=4, draw_lines=True, n_line=(1, 2),
                            draw_points=True, point_chance=2):
            width, height = size
            # 定义使用Image类实例化一个长120,宽30,基于RGB的(255.255.255)颜色的图片
            img = Image.new(mode, size, bg_color)
            # 创建画笔,用于在图片上生成内容
            draw = ImageDraw.Draw(img)
    
            def get_chars():
                return random.sample(self._letter_cases, length)
    
            def creat_line():
                line_num = random.randint(*n_line)  # sign that the param is a list
    
                for i in range(line_num):
                    begin = (random.randint(
                        0, size[0]), random.randint(0, size[1]))
                    end = (random.randint(0, size[0]), random.randint(0, size[1]))
                    draw.line([begin, end], fill=(0, 0, 0))
            # 在图片上生成点
            def create_points():
                chance = min(100, max(0, int(point_chance)))
                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 create_strs():
                c_chars = get_chars()
                strs = ' %s ' % ' '.join(c_chars)
                font = ImageFont.truetype(font_type, font_size)
                font_width, font_height = font.getsize(strs)
                draw.text(((width - font_width) / 3, (height - font_height) / 3),
                          strs, font=font, fill=fg_color)
                return ''.join(c_chars)
    
            if draw_lines:
                creat_line()
            if draw_points:
                create_points()
            strs = create_strs()
    
            params = [1 - float(random.randint(1, 2)) / 100,
                      0,
                      0,
                      0,
                      1 - float(random.randint(1, 10)) / 100,
                      float(random.randint(1, 2)) / 500,
                      0.001,
                      float(random.randint(1, 2)) / 500
                      ]
            img = img.transform(size, Image.PERSPECTIVE, params)
            img = img.filter(ImageFilter.EDGE_ENHANCE_MORE)
            return img, strs
    
    
    def cre_code():
        vecode = VerifyCode()
        code_img, capacha_code = vecode.createCodeImage()
        msstream = BytesIO()
        code_img.save(msstream, "gif")
        code = msstream.getvalue()
    
        return code, capacha_code
    
    
    image, text = cre_code()
    # image 为二进制流
    
    print(image)
    print("图片验证码:%s" % text)
    # with open('./ image.gif ', 'wb') as pic:
    #     pic.write(image)
    
    

    为了服务端验证,还需要在请求验证码时请求一个ID,供后续服务器验证ID和验证码的值。
    参考代码2如下:

    from CAPTCHA import cre_code
    
    
    class ImageCodeView(APIView):
        """图片验证码"""
    
        def get(self, request, vcode_id):
            # 生成验证码图片
            image, text = cre_code()
    
            # 保存真实值
            # redis_conn = get_redis_connection('verify_codes')
            # redis_conn.setex("img_%s" % vcode_id, 5 * 60, text)
    
            print("图片验证码:%s" % text)
    
            # 返回图片
            return HttpResponse(image, content_type='image/gif')
    
    

    代码1执行的结果参考如下所示:

    保存到本地可见如下图片:

    No pains, No gains
  • 相关阅读:
    给asterisk写app供CLI调用
    C++实现raw_input
    CentOS6下配置本地用户访问vsftpd,并赋予写权限
    用SqlServer存储Asterisk的呼叫记录
    go 1发布了,之前写的代码不能运行了
    字符串分割(C++)
    asterisk事件监控
    git的简单使用
    用Python访问SqlServer
    像Python那样跑go1的代码(Windows下双击运行)
  • 原文地址:https://www.cnblogs.com/Rightsec/p/15130663.html
Copyright © 2011-2022 走看看