该实例是基于Django框架和Pillow模块实现的动态获取验证码,下面是实现过程推导。
创建路由和视图函数,在路由中添加get_code路由,视图中创建get_code试图函数。
- 推导一:打开本地文件发送二进制数据
view.py:
def get_code(request):
with open(r'002_wLZfWbk.jpg','rb') as f:
data = f.read()
return HttpResponse(data)
get_code.html:
<img src="/get_code/" alt="" width="310" height="60" id="id_img">
通过上面的实例说明HttpResponse可以向前端发送二进制数据。
- 推导二:动态生成图片发送二进制数据
因为要动态生成图片,这里就需要利用Pillow模块来实现了,pip install pillow
安装pillow模块。
官方文档:https://pillow.readthedocs.io/en/stable/
Pillow由PIL而来,所以该导入该库使用import PIL
# Image用来生成图片
from PIL import Image
def get_code(request):
# img_obj = Image.new('RGB',(310,60),'green') # 第二个参数规定生成的图片大小,要与前端设置的一样
img_obj = Image.new('RGB',(310,60),(128,128,128)) # 第三个参数既可以传颜色英文也可以传rgb参数
# 先保存成文件
with open('demo.png','wb') as f:
img_obj.save(f)
# 再以二进制模式读取发送数据
with open('demo.png','rb') as f:
data = f.read()
return HttpResponse(data)
- 推导三:图片颜色动态变化 ,图片存放不再依赖于文件的形式
想要生成的不保存位文件,这里有需要另一个模块io
from PIL import Image
from io import BytesIO
# 能够帮你保存数据 并且在取的时候会以二进制的形式返回给你
# 随机生成rgb参数
def get_random():
return random.randint(0,255),random.randint(0,255),random.randint(0,255)
def get_code(request):
img_obj = Image.new('RGB',(310,60),get_random())
# 生成一个BytesIO对象
io_obj = BytesIO() # 将这个对象看成文件句柄
img_obj.save(io_obj,'png') # 将图片数据存入内存管理器中,注意需要指定图片格式
return HttpResponse(io_obj.getvalue()) # 将保存的数据以二进制的数据返回出来
- 推到四:终极版
# Image用来生成图片,ImageDraw在图片上写'字',ImageFont字体样式,ImageFilter图片模糊处理
from PIL import Image,ImageDraw,ImageFont,ImageFilter
# 能够保存数据 并且在取的时候会以二进制的形式返回
from io import BytesIO
import random
# 随机生成rgb参数
def get_random():
return random.randint(0,255),random.randint(0,255),random.randint(0,255)
def get_code(request):
# 定义生成的图像的尺寸
width = 320
height = 56
# 生成图片对象
img_obj = Image.new('RGB',(width ,height),get_random())
# 生成一个画笔对象
img_draw = ImageDraw.Draw(img_obj) # 你的画笔就可以在该图片上为所欲为
# 生成一个字体对象
img_font = ImageFont.truetype('mo.ttf',45) # 在文件夹中添加ttf字体文件,35代表字体文件
# 随机5位验证码: 数字+小写字母+大写字母
code = '' # 定义一个变量存储最终验证码
for i in range(5):
random_int = str(random.randint(0,9))
random_lower = chr(random.randint(97,122))
random_upper = chr(random.randint(65,90))
temp_code = random.choice([random_int,random_lower,random_upper])
# 将产生的字一个一个的写到图片上
img_draw.text((60+i*45,0),temp_code,get_random(),img_font) # (60+i*45,0)规定字在图片上的位置
# 将生成验证码记录,在实际项目中可以将验证码保存在session表中,方便后面的验证。
code += temp_code
for i in range(10):
x1 = random.randint(0, width)
x2 = random.randint(0, width)
y1 = random.randint(0, height)
y2 = random.randint(0, height)
# 在图片上画线
img_draw.line((x1, y1, x2, y2), fill=get_random(),width=2)
for i in range(100):
# 画点
img_draw.point([random.randint(0, width), random.randint(0, height)], fill=get_random())
x = random.randint(0, width)
y = random.randint(0, height)
# 画弧形
img_draw.arc((x, y, x + 4, y + 4), 0, 90, fill=get_random())
print(code)
# 生成io对象
io_obj = BytesIO()
# 对图片模糊
img_obj = img_obj.filter(ImageFilter.BoxBlur(radius=2))
# 将图片数据存入内存管理器中,注意需要指定图片格式
img_obj.save(io_obj,'png')
# 将保存的数据以二进制的数据返回出来
return HttpResponse(io_obj.getvalue())
前端代码
<div>
<img src="/get_code/" alt="" width="315" height="60" id="id_img">
</div>
<script>
//通过点击图片,图片会进行更新
var func = function (){
let old_path = $('#id_img').attr('src');
$('#id_img').attr('src', old_path + '?')
};
$('#id_img').click(function () {
func();
});
</script>
最终效果图: