Django之图形验证码
目录
- Django之图形验证码
- 【1】静态图片
- 【2】视图层绑定静态文件
- 【3】PIL生成图片(固定背景)
- 【4】将图片存储在内存
- 【5】生成文本信息
- 【6】实现图片刷新
【1】静态图片
最基础的生成图片就是获取静态文件
<div style="margin-left: 10px;">
<img src="{% static 'img/img.png' %}" width="100%" height="37px">
</div>
【2】视图层绑定静态文件
# urls.py
path('get_verify_img/', views.get_verify_img, name='get_verify_img'),
# views.py
import os
from django.conf import settings
def get_verify_img(request):
img_path = os.path.join(settings.BASE_DIR, 'Blog/static/img/img3.png')
with open(img_path, 'rb') as f:
data = f.read()
return HttpResponse(data)
<img src="{% url 'Blog:get_verify_img' %}" width="100%" height="37px">
【3】PIL生成图片(固定背景)
安装Pillow模块
pip install Pillow
导入
from PIL import Image, ImageDraw, ImageFont
# Image:负责生成图片数据
# ImageDraw:在生成的图片上面添加相应数据
# ImageFont:添加相应数据时指定字体样式、大小、间距
from PIL import Image, ImageDraw, ImageFont
def get_verify_img(request):
# 图片名称
img_name = 'verify.png'
# 指定图像模式
mode = 'RGB'
# 指定图像尺寸
size = (123, 37)
# 指定图像颜色(颜色名或三原色盘)
color = 'blue'
# 创建图片对象
img_obj = Image.new(mode=mode, size=size, color=color)
# 设置图片保存路径
img_path = os.path.join(settings.BASE_DIR, 'Blog/static/img', img_name)
# 保存图片
img_obj.save(img_path)
# 读取图片
with open(img_path, 'rb') as f:
data = f.read()
return HttpResponse(data)
【4】将图片存储在内存
要将数据临时存储在内存需要借助Python的IO模块
from io import BytesIO, StringIO
# BytesIO:负责临时存储数据
# StringIO:负责取出数据
顺便把随机颜色做了
def random_rgb():
return random.randint(0, 256), random.randint(0, 256), random.randint(0, 256)
def get_verify_img(request):
img_name = 'verify.png'
# 指定图像模式
mode = 'RGB'
# 指定图像尺寸
size = (123, 37)
# 随机生成图像颜色
color = random_rgb()
img_obj = Image.new(mode=mode, size=size, color=color)
# 创建存储内存空间
io_obj = BytesIO()
# 保存图片并指定后缀
img_obj.save(io_obj, 'png')
# 取出图片
data = io_obj.getvalue()
return HttpResponse(data)
【5】生成文本信息
先生成一个随机的五位数文本
def random_word():
# 0-9数字
random_num = random.randint(0, 9)
# a-z
random_lower = chr(random.randint(97, 122))
# A-Z
random_upper = chr(random.randint(65, 90))
word = random.choice([random_upper, random_lower, str(random_num)])
return word
def get_verify_img(request):
img_name = 'verify.png'
# 指定图像模式
mode = 'RGB'
# 指定图像尺寸
size = (123, 50)
# 随机生成图像颜色
color = random_rgb()
img_obj = Image.new(mode=mode, size=size, color=color)
# 创建画笔对象
img_draw = ImageDraw.Draw(img_obj)
# 设置字体和大小
img_font = ImageFont.truetype('Blog/static/font/TianShiBaoDiaoTiJian-1.ttf', 34)
code = ''
for i in range(0, 4):
word = random_word()
# text依次放入参数(坐标,文本内容,字体颜色,字体样式)
img_draw.text((i * 15 + 20, 4), word, random_rgb(), img_font)
code += word
# 创建存储内存空间
io_obj = BytesIO()
# 保存图片并指定后缀
img_obj.save(io_obj, 'png')
# 取出图片
data = io_obj.getvalue()
return HttpResponse(data)
实例效果
【6】实现图片刷新
首先需要知道刷新图片的原理
当这种验证图片数据在开发者模式中将它的末尾添加?
并加入任意数字后按下回车他就会自动变换
http://127.0.0.1:8000/Blog/get_verify_img/
<img src="{% url 'Blog:get_verify_img' %}" width="100%"
height="37px" id="img_verify" alt="">
<script>
const verify = document.getElementById('img_verify')
verify.addEventListener('click', function () {
// 获取原始的 src 属性值
const verify_src = verify.src;
// 检查原始 src 是否已经包含时间戳
if (verify_src.includes('?')) {
// 如果已经包含时间戳,只替换最后一个时间戳
verify.src = verify_src.replace(/\?.*$/, '') + '?' + new Date().getTime();
} else {
// 如果原始 src 没有时间戳,直接添加时间戳
verify.src = verify_src + '?' + new Date().getTime();
}
})
</script>
后端将生成图片验证码拆分到新的文件
import random
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO, StringIO
def random_rgb():
return random.randint(0, 256), random.randint(0, 256), random.randint(0, 256)
def random_word():
# 0-9数字
random_num = random.randint(0, 9)
# a-z
random_lower = chr(random.randint(97, 122))
# A-Z
random_upper = chr(random.randint(65, 90))
word = random.choice([random_upper, random_lower, str(random_num)])
return word
def verify():
img_name = 'verify.png'
data = None
# 指定图像模式
mode = 'RGB'
# 指定图像尺寸
size = (100, 50)
# 随机生成图像颜色
color = random_rgb()
img_obj = Image.new(mode=mode, size=size, color=color)
img_draw = ImageDraw.Draw(img_obj)
img_font = ImageFont.truetype('Blog/static/font/TianShiBaoDiaoTiJian-1.ttf', 35)
code = ''
words = ''
for i in range(0, 4):
word = random_word()
# text依次放入参数(坐标,文本内容,字体颜色,字体样式)
img_draw.text((i * 15 + 20, 4), word, random_rgb(), img_font)
code += word
# 创建存储内存空间
io_obj = BytesIO()
# 保存图片并指定后缀
img_obj.save(io_obj, 'png')
# 取出图片
data = io_obj.getvalue()
words += word
print(words)
# 返回图片数据,验证码文本
return data,words
视图层代码
# 文件路径自定义
from lib.verify_img.verify import verify
def get_verify_img(request):
data, words = verify()
print(words)
return HttpResponse(data)