假设我们有一个fonts的文件夹,里面有1.ttf,2.ttf,3.ttf三个字体文件
具体代码实现代码codes.py:
- # coding:utf8
- from PIL import ImageDraw, ImageColor, ImageFile, ImageFont, ImageFilter, Image
- import random
- import os
- import uuid
- class Codes:
- # 定义随机字符
- def random_chr(self):
- num = random.randint(1, 3)
- if num == 1:
- char = random.randint(48, 57)
- elif num == 2:
- char = random.randint(97, 122)
- else:
- char = random.randint(65, 90)
- return chr(char)
- # 定义干扰字符
- def random_dis(self):
- arr = ["~", "^", "_", "."]
- return arr[random.randint(0, len(arr) - 1)]
- # 定义干扰字符的颜色
- def random_color1(self):
- return (random.randint(64, 255), random.randint(64, 255), random.randint(64, 255))
- def random_color2(self):
- return (random.randint(32, 127), random.randint(32, 127), random.randint(32, 127))
- # 生成验证码
- def create_code(self):
- width = 200
- height = 60
- # 创建一个画布图片
- image = Image.new("RGB", (width, height), (192, 192, 192))
- # 创建font对象,定义字体以及大小
- font_name = random.randint(1, 3)
- font_file = os.path.join(os.path.dirname(__file__), "fonts") + "/" + "%d.ttf" % font_name
- font = ImageFont.truetype(font_file, 30)
- # 填充像素点
- draw = ImageDraw.Draw(image)
- for x in range(0, width, 5):
- for y in range(0, height, 5):
- draw.point((x, y), fill=self.random_color1())
- # 填充干扰字符
- for v in range(0, width, 30):
- dis = self.random_dis()
- w = 5 + v
- h = random.randint(5, 15)
- draw.text((w, h), dis, font=font, fill=self.random_color1())
- # 填充字符
- chars = ""
- for v in range(4):
- c = self.random_chr()
- chars += str(c)
- h = random.randint(5, 15)
- w = width / 4 * v + 10
- draw.text((w, h), c, font=font, fill=self.random_color2())
- # 模糊效果
- image = filter(ImageFilter.BLUR)
- # 保证图片名称的唯一性
- image_name = "%s.jpg" % uuid.uuid4().hex
- save_dir = os.path.join(os.path.dirname(__file__), "codes")
- if not os.path.exists(save_dir):
- os.makedirs(save_dir)
- image.save(save_dir + '/' + image_name)
- return dict(
- img_name=image_name,
- code=chars
- )
应用
flask项目中
- 在定义路由的views.py文件中引用。自定义一个"/codes/"的路由,用来GET到验证码
- # 验证码
- @app.route('/codes/', methods=["GET"])
- def codes():
- from codes import Codes
- c = Codes()
- info = c.create_code()
- image = os.path.join(os.path.dirname(__file__), "static/code") + "/" + info["img_name"]
- with open(image, "rb") as f:
- image = f.read()
- session["code"] = info["code"]
- return Response(image, mimetype="jpeg")
上面读取到图片并显示出来了,将验证码的值给到session["code"]来存储,这样访问http:xxx.xx.xx./codes/就可以获取到验证码的图片,并保存在本地code的文件夹中
- 然后在前端页面验证码图片显示的的地方引用,点击图片会重新切换生成一个
- <img alt="点击切换验证码" title="点击切换" src="/codes/" onclick="this.src='/codes/?' + Math.random()"
- style="width: 180px; height:50px; margin-top: 6px;">
- 在forms.py文件中存入session的code与code表单的输入的值进行对比判断
- # 自定义验证码验证功能
- def validate_code(self,field):
- code = field.data
- # if not session.has_key("code"): python2写法
- if "code" not in session:
- raise ValidationError("没有验证码")
- # if session.has_key("code") and session["code"].lower() != code.lower():python2写法
- if "code" in session and session["code"].lower() != code.lower(): # 从views中获取session的"code"
- raise ValidationError("验证码错误")
本文作者为olei,转载请注明。
好文章,不错[aru_1]自己改改,整个小孟坤[aru_4]
@陈鑫威博客大神抬举了[aru_41]