Tornaod 登录获取验证码

 

app.py:

 1 import tornado.ioloop
 2 import tornado.web
 3 import io
 4 import check_code
 5 
 6 class CheckCodeHandler(tornado.web.RequestHandler):
 7     def get(self):
 8         mstream = io.BytesIO()
 9         img, code = check_code.create_validate_code()
10         img.save(mstream, "GIF")
11         # self.session["CheckCode"] = code
12         print(mstream.getvalue())
13         self.write(mstream.getvalue())
14 
15 class MainHandler(tornado.web.RequestHandler):
16     def get(self):
17         self.render('index.html')
18 
19 settings = {
20     'template_path': 'template',
21     'static_path': 'static',
22     'static_url_prefix': '/static/',
23     'cookie_secret': 'aiuasdhflashjdfoiuashdfiuh',
24 }
25 
26 application = tornado.web.Application([
27     (r"/index", MainHandler),
28     (r"/check_code", CheckCodeHandler),
29 ], **settings)
30 
31 
32 if __name__ == "__main__":
33     application.listen(8888)
34     tornado.ioloop.IOLoop.instance().start()
app.py

 

check_code.py:

  1 #!/usr/bin/env python
  2 #coding:utf-8
  3 
  4 import random
  5 from PIL import Image, ImageDraw, ImageFont, ImageFilter
  6 
  7 _letter_cases = "abcdefghjkmnpqrstuvwxy"  # 小写字母,去除可能干扰的i,l,o,z
  8 _upper_cases = _letter_cases.upper()  # 大写字母
  9 _numbers = ''.join(map(str, range(3, 10)))  # 数字
 10 init_chars = ''.join((_letter_cases, _upper_cases, _numbers))
 11 
 12 def create_validate_code(size=(120, 30),
 13                          chars=init_chars,
 14                          img_type="GIF",
 15                          mode="RGB",
 16                          bg_color=(255, 255, 255),
 17                          fg_color=(0, 0, 255),
 18                          font_size=18,
 19                          font_type="Monaco.ttf",
 20                          length=4,
 21                          draw_lines=True,
 22                          n_line=(1, 2),
 23                          draw_points=True,
 24                          point_chance = 2):
 25     '''
 26     @todo: 生成验证码图片
 27     @param size: 图片的大小,格式(宽,高),默认为(120, 30)
 28     @param chars: 允许的字符集合,格式字符串
 29     @param img_type: 图片保存的格式,默认为GIF,可选的为GIF,JPEG,TIFF,PNG
 30     @param mode: 图片模式,默认为RGB
 31     @param bg_color: 背景颜色,默认为白色
 32     @param fg_color: 前景色,验证码字符颜色,默认为蓝色#0000FF
 33     @param font_size: 验证码字体大小
 34     @param font_type: 验证码字体,默认为 ae_AlArabiya.ttf
 35     @param length: 验证码字符个数
 36     @param draw_lines: 是否划干扰线
 37     @param n_lines: 干扰线的条数范围,格式元组,默认为(1, 2),只有draw_lines为True时有效
 38     @param draw_points: 是否画干扰点
 39     @param point_chance: 干扰点出现的概率,大小范围[0, 100]
 40     @return: [0]: PIL Image实例
 41     @return: [1]: 验证码图片中的字符串
 42     '''
 43 
 44     width, height = size # 宽, 高
 45     img = Image.new(mode, size, bg_color) # 创建图形
 46     draw = ImageDraw.Draw(img) # 创建画笔
 47 
 48     def get_chars():
 49         '''生成给定长度的字符串,返回列表格式'''
 50         return random.sample(chars, length)
 51 
 52     def create_lines():
 53         '''绘制干扰线'''
 54         line_num = random.randint(*n_line) # 干扰线条数
 55 
 56         for i in range(line_num):
 57             # 起始点
 58             begin = (random.randint(0, size[0]), random.randint(0, size[1]))
 59             #结束点
 60             end = (random.randint(0, size[0]), random.randint(0, size[1]))
 61             draw.line([begin, end], fill=(0, 0, 0))
 62 
 63     def create_points():
 64         '''绘制干扰点'''
 65         chance = min(100, max(0, int(point_chance))) # 大小限制在[0, 100]
 66 
 67         for w in range(width):
 68             for h in range(height):
 69                 tmp = random.randint(0, 100)
 70                 if tmp > 100 - chance:
 71                     draw.point((w, h), fill=(0, 0, 0))
 72 
 73     def create_strs():
 74         '''绘制验证码字符'''
 75         c_chars = get_chars()
 76         strs = ' %s ' % ' '.join(c_chars) # 每个字符前后以空格隔开
 77 
 78         font = ImageFont.truetype(font_type, font_size)
 79         font_width, font_height = font.getsize(strs)
 80 
 81         draw.text(((width - font_width) / 3, (height - font_height) / 3),
 82                     strs, font=font, fill=fg_color)
 83 
 84         return ''.join(c_chars)
 85 
 86     if draw_lines:
 87         create_lines()
 88     if draw_points:
 89         create_points()
 90     strs = create_strs()
 91 
 92     # 图形扭曲参数
 93     params = [1 - float(random.randint(1, 2)) / 100,
 94               0,
 95               0,
 96               0,
 97               1 - float(random.randint(1, 10)) / 100,
 98               float(random.randint(1, 2)) / 500,
 99               0.001,
100               float(random.randint(1, 2)) / 500
101               ]
102     img = img.transform(size, Image.PERSPECTIVE, params) # 创建扭曲
103 
104     img = img.filter(ImageFilter.EDGE_ENHANCE_MORE) # 滤镜,边界加强(阈值更大)
105 
106     return img, strs
check_code.py

 

index.html:

 1 <!DOCTYPE html>
 2 <html>
 3 <head lang="en">
 4     <meta charset="UTF-8">
 5     <title></title>
 6 </head>
 7 <body>
 8     <h1>hello</h1>
 9     <form action="/index" method="post" enctype="multipart/form-data">
10         <p><input name="user" type="text" placeholder="用户名" /></p>
11         <p><input name="pwd" type="password" placeholder="密码" /></p>
12         <p>
13             <input name='code' type="text" placeholder="验证码" />
14             <img src="/check_code" onclick='ChangeCode();' id='imgCode'>
15         </p>
16         <input type="submit" />
17     </form>
18     <script type="text/javascript">
19 
20         function ChangeCode() {
21             var code = document.getElementById('imgCode');
22             code.src += '?';
23         }
24     </script>
25 </body>
26 </html>
index.html

 

 

  

posted on 2018-07-25 21:08  Eric_nan  阅读(147)  评论(0)    收藏  举报