1 from PIL import Image, ImageDraw, ImageFont, ImageFilter 2 from flask import make_response 3 from flask import render_template 4 from flask import request 5 from io import BytesIO 6 from flask import Flask 7 from datetime import timedelta 8 import datetime 9 import random 10 11 def check_code(width=120, height=30, char_length=5, font_file=‘Monaco.ttf‘, font_size=28): 12 code = [] 13 img = Image.new(mode=‘RGB‘, size=(width, height), color=(255, 255, 255)) 14 draw = ImageDraw.Draw(img, mode=‘RGB‘) 15 16 def rndChar(): 17 """ 18 生成随机字母 19 :return: 20 """ 21 return chr(random.randint(65, 90)) 22 23 def rndColor(): 24 """ 25 生成随机颜色 26 :return: 27 """ 28 return (random.randint(0, 255), random.randint(10, 255), random.randint(64, 255)) 29 30 # 写文字 31 font = ImageFont.truetype(font_file, font_size) 32 for i in range(char_length): 33 char = rndChar() 34 code.append(char) 35 h = random.randint(0, 4) 36 draw.text([i * width / char_length, h], char, font=font, fill=rndColor()) 37 38 # 写干扰点 39 for i in range(40): 40 draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor()) 41 42 # 写干扰圆圈 43 for i in range(40): 44 draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor()) 45 x = random.randint(0, width) 46 y = random.randint(0, height) 47 draw.arc((x, y, x + 4, y + 4), 0, 90, fill=rndColor()) 48 49 # 画干扰线 50 for i in range(5): 51 x1 = random.randint(0, width) 52 y1 = random.randint(0, height) 53 x2 = random.randint(0, width) 54 y2 = random.randint(0, height) 55 56 draw.line((x1, y1, x2, y2), fill=rndColor()) 57 58 img = img.filter(ImageFilter.EDGE_ENHANCE_MORE) 59 return img, ‘‘.join(code) 60 61 app = Flask(__name__, template_folder=‘../templates‘, static_folder=‘../static‘) 62 63 @app.route(‘/‘) 64 def login(): 65 return render_template(‘code.html‘) 66 67 @app.route(‘/code‘, endpoint=‘code‘) 68 def image_code(): 69 """ 生成图片验证码 """ 70 71 image_object, code = check_code() 72 stream = BytesIO() 73 image_object.save(stream, ‘png‘) 74 response = make_response(stream.getvalue()) 75 76 # expires:datatime类型,使用此参数,需参照格林尼治时间,即北京时间-8个小时 77 # expires = datetime.datetime.now()+timedelta(seconds=10) 78 response.set_cookie(‘image_code‘, code, max_age=100) # 10秒 79 return response 80 81 @app.route(‘/check‘) 82 def check(): 83 image_code = request.cookies.get(‘image_code‘) 84 print(image_code) 85 if not image_code: 86 response = make_response(‘对不起,你的验证码已经过时了!‘) 87 return response 88 return make_response(‘你的验证码为:‘ + image_code) 89 90 if __name__ == ‘__main__‘: 91 app.run()
前端部分:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>验证码</title> </head> <body> <img src="{{ url_for(‘code‘,_external=True) }}" id="imageCode" title="点击更换图片"> </body> </html> <script src="{{ url_for(‘static‘,filename=‘js/jquery-2.1.1.js‘)}}"></script> <script> $(function () { $(‘#imageCode‘).click(function () { var oldSrc = $(this).attr(‘src‘); $(this).attr(‘src‘, oldSrc + "?"); }) }) </script>
效果展示:
有效期: