Django之图形验证码

Django之图形验证码

目录

【1】静态图片

最基础的生成图片就是获取静态文件

html 复制代码
<div style="margin-left: 10px;">
    <img src="{% static 'img/img.png' %}" width="100%" height="37px">
</div>

【2】视图层绑定静态文件

python 复制代码
# urls.py
path('get_verify_img/', views.get_verify_img, name='get_verify_img'),
python 复制代码
# 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)
html 复制代码
<img src="{% url 'Blog:get_verify_img' %}" width="100%" height="37px">

【3】PIL生成图片(固定背景)

安装Pillow模块

shell 复制代码
pip install Pillow

导入

python 复制代码
from PIL import Image, ImageDraw, ImageFont

# Image:负责生成图片数据
# ImageDraw:在生成的图片上面添加相应数据
# ImageFont:添加相应数据时指定字体样式、大小、间距
python 复制代码
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模块

python 复制代码
from io import BytesIO, StringIO
# BytesIO:负责临时存储数据
# StringIO:负责取出数据

顺便把随机颜色做了

python 复制代码
def random_rgb():
    return random.randint(0, 256), random.randint(0, 256), random.randint(0, 256)
python 复制代码
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】生成文本信息

先生成一个随机的五位数文本

python 复制代码
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
python 复制代码
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】实现图片刷新

首先需要知道刷新图片的原理

当这种验证图片数据在开发者模式中将它的末尾添加?并加入任意数字后按下回车他就会自动变换

python 复制代码
http://127.0.0.1:8000/Blog/get_verify_img/
html 复制代码
<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>

后端将生成图片验证码拆分到新的文件

python 复制代码
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

视图层代码

python 复制代码
# 文件路径自定义
from lib.verify_img.verify import verify

def get_verify_img(request):
    data, words = verify()
    print(words)
    return HttpResponse(data)
相关推荐
日里安1 小时前
8. 基于 Redis 实现限流
数据库·redis·缓存
EasyCVR1 小时前
ISUP协议视频平台EasyCVR视频设备轨迹回放平台智慧农业视频远程监控管理方案
服务器·网络·数据库·音视频
Elastic 中国社区官方博客1 小时前
使用真实 Elasticsearch 进行更快的集成测试
大数据·运维·服务器·数据库·elasticsearch·搜索引擎·集成测试
Amo Xiang2 小时前
Django 2024全栈开发指南(一):框架简介、环境搭建与项目结构
python·django
明月与玄武2 小时前
关于性能测试:数据库的 SQL 性能优化实战
数据库·sql·性能优化
Amo Xiang3 小时前
Django 2024全栈开发指南(二):Django项目配置详解
python·django
PGCCC4 小时前
【PGCCC】Postgresql 存储设计
数据库·postgresql
PcVue China5 小时前
PcVue + SQL Grid : 释放数据的无限潜力
大数据·服务器·数据库·sql·科技·安全·oracle
魔道不误砍柴功7 小时前
简单叙述 Spring Boot 启动过程
java·数据库·spring boot
锐策7 小时前
〔 MySQL 〕数据库基础
数据库·mysql