Django生成验证码图片

发布时间 2023-03-23 09:17:53作者: super_ip

1、安装和准备

pip install pillow

准备一款字体重命名为【Monaco.ttf】放在项目的根目录下

2、生成验证码图片代码

import random
from PIL import Image, ImageDraw, ImageFont, ImageFilter


def check_code(width=120, height=30, char_length=5, font_file='Monaco.ttf', font_size=28):
code = []
img = Image.new(mode='RGB', size=(width, height), color=(255, 255, 255))
draw = ImageDraw.Draw(img, mode='RGB')

def rndChar():
"""
生成随机字母
:return:
"""
return chr(random.randint(65, 90))
# return str(random.randint(0, 9))

def rndColor():
"""
生成随机颜色
:return:
"""
return (random.randint(0, 255), random.randint(10, 255), random.randint(64, 255))

# 写文字
font = ImageFont.truetype(font_file, font_size)
for i in range(char_length):
char = rndChar()
code.append(char)
h = random.randint(0, 4)
draw.text([i * width / char_length, h], char, font=font, fill=rndColor())

# 写干扰点
for i in range(40):
draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())

# 写干扰圆圈
for i in range(40):
draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())
x = random.randint(0, width)
y = random.randint(0, height)
draw.arc((x, y, x + 4, y + 4), 0, 90, fill=rndColor())

# 画干扰线
for i in range(5):
x1 = random.randint(0, width)
y1 = random.randint(0, height)
x2 = random.randint(0, width)
y2 = random.randint(0, height)

draw.line((x1, y1, x2, y2), fill=rndColor())

img = img.filter(ImageFilter.EDGE_ENHANCE_MORE)
return img, ''.join(code)


if __name__ == '__main__':
img, code_str = check_code()
print(code_str)

with open('code.png', 'wb') as f:
img.save(f, format='png')

3、内存读写应用验证码图片代码

视图函数

from utils.code import check_code
from io import BytesIO


def image_code(request):
"""生成图片验证码"""
img, code_string = check_code()

# 利用session,将这个用户的验证码写入在session当中,以便后续获取验证码以进行校验
# request.session["image_code"] = code_string

# 给session设置60秒超时,即验证码超时
# request.session.set_expiry(60)

stream = BytesIO()
img.save(stream, 'png')

return HttpResponse(stream.getvalue())

HTML

<div class="form-group">
<div class="clearfix">
<label for="id_code">图片验证码</label>
<div class="row">
<div class="col-xs-7">
{{ form.code }}
<span style="color: red;">{{ form.code.errors.0 }}</span>
</div>

<div class="col-xs-5">
{# <img id="image_code" src="{% static 'img/code.jpg' %}" style="height: 125px" >#}
<img id="image_code" src="/image/code" style="width: 125px">
</div>
</div>
</div>

4、点击验证码刷新图片

<script src="{% static 'js/jquery-3.6.0.min.js' %}"></script>
<script src="{% static 'plugins/bootstrap-3.4.1/js/bootstrap.min.js' %}"></script>
<script>
$(function () {
$("#image_code").click(function () {
var oldSrc = $(this).attr('src');
$(this).attr('src', oldSrc + "?")
})
})
</script>