Django之图形验证码
目录
【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)










