☰
python 生成验证码 前后端分离项目 用到redis
2026/10/22 1:47:40 网站建设 项目流程
import os.path import random import string from PIL import Image,ImageFont,ImageDraw,ImageFilter class ImageVerify: def __init__(self,x=140,y=40,length=4,size=28): ''' 初始化方法 :param x: 图片的宽度 px 像素 :param y: 图片的高度 :param length: 文字的个数 :param size: 字体的大小 px ''' self.x=x self.y=y self.length=length self.size=size #生成图片里面的随机文字 def random_str(self): ''' 随机生成指定长度的字符串 验证码的文字:字母+数字组成 :return: 返回生成的四个字符 ''' #所有的字母+所有数字 随机字符的范围 source=string.ascii_letters+string.digits result=''.join(random.sample(source,self.length)) #print(result) return result #随机生成文字的颜色 0-255 def random_color(self,start=0,end=255): ''' 随机生成rgb(红绿蓝)颜色 rgb(100,25,30) :param start:颜色范围的最小值 :param end:颜色范围的最大值 :return:颜色值的元组 ''' result=[random.randint(start,end) for i in range(3)] #列表推导表达式 #print(result) return tuple(result) #转元组 #生成干扰线 在画布上进行绘画 通过两个点确定一条线 def random_lines(self,draw): ''' :param draw: 画笔对象 :return: 没有返回值 调用时进行绘画的操作 ''' #根据文字的个数来决定绘制线条的个数 for i in range(self.length): #干扰线的起点x轴,y轴 lines=[(random.randint(0,self.x),random.randint(0,self.y)) for i in range(2)] #通过画笔对象 调用画线条的方法 fill指定线条的颜色 draw.line(lines,fill=self.random_color(64,200)) #生成干扰点 def random_points(self,draw,rate): ''' 绘制干扰点 :param draw: 画笔对象 :param rate: 生成干扰点频率 密集性 :return: 没有返回值 调用时进行绘画的操作 ''' #得到像素点 for x in range(self.x): for y in range(self.y): if random.randint(1,100) <= rate: draw.point((x,y),fill=self.random_color(64,200)) #组装成一张验证码的图片 def verify_code(self): ''' 生成验证码图片 组成以上多个方法 :return:返回验证码图片对象 ''' #创建一个画布对象 颜色通道 画布宽高 白色背景颜色 image=Image.new('RGB',(self.x,self.y),(255,255,255)) #创建font对象 字体 #需要用的字体文件 #os.path.abspath(__file__) #当前脚本所在的文件夹绝对路径 file=os.path.dirname(os.path.abspath(__file__) ) font=ImageFont.truetype(f'{file}/HYYakuHei-85W.ttf',self.size) #字体类型 字体大小 #创建画笔对象 在画布上创建画笔 draw=ImageDraw.Draw(image) #绘制干扰线和干扰点 self.random_lines(draw) self.random_points(draw,20) #绘制答案 code=self.random_str() #验证码的答案应该要写在什么地方 for i in range(self.length): #绘制文字 坐标 字符内容 字体 颜色 draw.text((35 * i + 5, random.randint(3, 6)), code[i], font=font, fill=self.random_color(32, 127)) #高斯模糊滤镜 image.filter(ImageFilter.BLUR) return image, code #判断 运行时 是该文件本身在运行,还是其他文件导入了这个模块在运行 # 当其他的文件导入该文件模块运行 并不会执行判断里面的代码 if __name__=='__main__': img = ImageVerify() image, code = img.verify_code() with open('code.png', 'wb') as fp: image.save(fp) print(code)

在视图中应用显示

from django_redis import get_redis_connection import io from utils.verifyUtil import ImageVerify class ImageVerifyView(View): def get(self, request,func,uuid): ''' :param request: 请求对象 :return: 验证码图片 ''' imageVerify = ImageVerify() # img保存的图片数据 img, code = imageVerify.verify_code() # 现在我们不需要把图片保存到服务器上面了 # 只需要将图片数据返回给到客户端 不需要做持久化的操作 # 图片是字节流 文件流:字符流 字节流 # 启动应用程序时 会划一部分的内存用于保存该文件 # 但是这个文件并不会实际存在在你的电脑当中 当程序结束,内存也会被释放,文件也会被删除,只会临时存在一段时间 # 生成一个临时的字节流文件对象 img_bytes = io.BytesIO() # 把图片数据保存到该字节流文件中 img.save(img_bytes, format='PNG') # 获取图片数据重新赋值 文件数据 img_bytes = img_bytes.getvalue() # 把uuid为键 验证码答案为值保存到redis数据库里面 cache = get_redis_connection(alias='verify_codes') #取别名 # KEY_TEMPLATE % (func, uuid) 为键 func 请求是登录还是注册 uuid 用户身份识别信息 # set在数据库里面添加一个键值对数据 code 为值 # EXPIRE_TIME过期时间 cache.set(KEY_TEMPLATE % (func, uuid), code, EXPIRE_TIME) return HttpResponse(img_bytes, content_type='image/png')

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询