zoukankan      html  css  js  c++  java
  • python模块PIL-获取带噪点噪线的随机验证码

    实际应用-噪点噪线验证码图片

    from PIL import Image
    from PIL import ImageDraw
    from PIL import ImageFont
    from io import BytesIO
    
    import random
    
    
    class ValidCodeImg:
        """
        生成一个经过降噪后的随机验证码的图片
        :return 生成图片的bytes类型的数据
        """
    
        def __init__(self, width=175, height=35, code_count=5,
                     font_size=32, point_count=10, line_count=3,
                     img_format='png'):
            #  图片宽度 单位px
            self.width = width
            # height: 图片高度 单位px
            self.height = height
            # code_count: 验证码个数
            self.code_count = code_count
            # font_size: 字体大小
            self.font_size = font_size
            # point_count: 噪点个数
            self.point_count = point_count
            # line_count: 划线个数
            self.line_count = line_count
            # img_format: 图片格式
            self.img_format = img_format
    
        @staticmethod
        def getrandomcolor():
            """获取一个随机颜色-(r,g,b)格式"""
            cor_r = random.randint(0, 255)
            cor_g = random.randint(0, 255)
            cor_b = random.randint(0, 255)
            return cor_r, cor_g, cor_b
    
        @staticmethod
        def getrandomstr():
            """获取一个随机字符串"""
            # 获取一个0-9的随机书
            num_str = str(random.randint(0, 9))
            # 获取一个A-Z的随机大写字母,65-90是大写字母的ascii码,通过chr转换成对应的字符
            upper_str = chr(random.randint(65, 90))
            # 获取一个a-z的随机小写字母,97-122是小写的ascii码,通过chr转换成对应的字符
            lower_str = chr(random.randint(97, 122))
            # 通过random模块的choice方法随机从以上的随机数字,大写字母和小写字母中获取一个字符,并返回
            random_str = random.choice((num_str, upper_str, lower_str))
            return random_str
    
        def getvalidcodeimg(self):
            """获取一个随机验证码图片"""
            # 通过Image.new(rgb格式, (图片的宽,图片的高), 颜色)获取一个Image对象
            img_obj = Image.new('RGB', (self.width, self.height), self.getrandomcolor())
            print(img_obj)
            # 通过ImageDraw.Draw(Image对象)获取一个画笔对象
            draw = ImageDraw.Draw(img_obj)
    
            # 通过ImageFont.truetype(字体文件路径, 字体大小)获取一个字体对象
            font = ImageFont.truetype(r'staticfontSTXINGKA.TTF', size=self.font_size)
    
            tmp_list = []  # 用于存储随机字符串
            for i in range(self.code_count):
                random_char = self.getrandomstr()
                # 在图片上写入得到的随机字符串,这样字符之间才会有距离,不会叠加
                # 通过画笔对象的text方法,即 draw.text((x, y), 字符串, 颜色, 字体)
                draw.text((10 + i * 32, -2), random_char, self.getrandomcolor(), font=font)
                # 将随机字符串保存
                tmp_list.append(random_char)
    
            # 将所有的字符串拼接,稍后返回,用于校验用户录入的记录是否正确
            valid_str = ''.join(tmp_list)
    
            # 噪线的生成
            for i in range(self.line_count):
                # 噪线的起点横坐标和纵坐标
                x1 = random.randint(0, self.width)
                y1 = random.randint(0, self.height)
                # 噪线的终点横坐标和纵坐标
                x2 = random.randint(0, self.width)
                y2 = random.randint(0, self.height)
                # 通过画笔对象draw.line((起点的xy, 终点的xy), fill='颜色')来划线
                draw.line((x1, y1, x2, y2), fill=self.getrandomcolor())
    
            # 噪点的生成
            for i in range(self.point_count):
                draw.point([random.randint(0, self.width), random.randint(0, self.height)], fill=self.getrandomcolor())
                x = random.randint(0, self.width)
                y = random.randint(0, self.height)
                draw.arc((x, y, x + 4, y + 4), 0, 40, fill=self.getrandomcolor())
    
            # 将生成的图片保存到内存中
            f = BytesIO()
            img_obj.save(f, self.img_format)
            data = f.getvalue()
            f.close()
    
            return data, valid_str
        
    
    # # 测试
    # if __name__ == '__main__':
    #     img = ValidCodeImg()
    #
    #     data, valid_str = img.getvalidcodeimg()
    #     print(valid_str)
    #
    #     with open(r'E:Desktopcode_test.png', 'wb') as f:
    #         f.write(data)
    
  • 相关阅读:
    PHP cURL模块
    phpweb成品网站最新版(注入、上传、写shell)
    首都师范大学2012年高等代数考研试题参考解答
    华南理工大学2020年数学分析考研试题参考解答
    四川大学2020年数学分析考研试题参考解答
    武汉大学2020年数学分析考研试题部分参考解答
    同济大学2020年高等代数考研试题部分参考解答
    同济大学2020年数学分析考研试题部分参考解答
    首都师范大学2020年数学分析考研试题参考解答
    首都师范大学2020年高等代数考研试题部分参考解答
  • 原文地址:https://www.cnblogs.com/xiaodan1040/p/12235323.html
Copyright © 2011-2022 走看看