python 生成验证码 前后端分离项目 用到redis import os.path import random import string from PIL import Image,ImageFont,ImageDraw,ImageFilter class ImageVerify: def __init__(self,x140,y40,length4,size28): 初始化方法 :param x: 图片的宽度 px 像素 :param y: 图片的高度 :param length: 文字的个数 :param size: 字体的大小 px self.xx self.yy self.lengthlength self.sizesize #生成图片里面的随机文字 def random_str(self): 随机生成指定长度的字符串 验证码的文字字母数字组成 :return: 返回生成的四个字符 #所有的字母所有数字 随机字符的范围 sourcestring.ascii_lettersstring.digits result.join(random.sample(source,self.length)) #print(result) return result #随机生成文字的颜色 0-255 def random_color(self,start0,end255): 随机生成rgb红绿蓝颜色 rgb(1002530) :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,fillself.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),fillself.random_color(64,200)) #组装成一张验证码的图片 def verify_code(self): 生成验证码图片 组成以上多个方法 :return:返回验证码图片对象 #创建一个画布对象 颜色通道 画布宽高 白色背景颜色 imageImage.new(RGB,(self.x,self.y),(255,255,255)) #创建font对象 字体 #需要用的字体文件 #os.path.abspath(__file__) #当前脚本所在的文件夹绝对路径 fileos.path.dirname(os.path.abspath(__file__) ) fontImageFont.truetype(f{file}/HYYakuHei-85W.ttf,self.size) #字体类型 字体大小 #创建画笔对象 在画布上创建画笔 drawImageDraw.Draw(image) #绘制干扰线和干扰点 self.random_lines(draw) self.random_points(draw,20) #绘制答案 codeself.random_str() #验证码的答案应该要写在什么地方 for i in range(self.length): #绘制文字 坐标 字符内容 字体 颜色 draw.text((35 * i 5, random.randint(3, 6)), code[i], fontfont, fillself.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, formatPNG) # 获取图片数据重新赋值 文件数据 img_bytes img_bytes.getvalue() # 把uuid为键 验证码答案为值保存到redis数据库里面 cache get_redis_connection(aliasverify_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_typeimage/png)