工具插件verifycode.py中,记得使用时需要在路由根目录中引入文字资源文件

# coding:utf8
# __author: Administrator
# date: //
# /usr/bin/env python
import random,os
from PIL import Image,ImageDraw,ImageFont,ImageFilter class CreateCode:
def __init__(self,size=(,),img_type="GIF",mode="RGB",bg_color=(,,),
fg_color=(,,),font_size=,font_type="Monaco.ttf",length=,
draw_lines=True,n_line = (,),draw_points=True,point_chance=):
'''
@todo: 生成验证码图片
@param size: 图片的大小,格式(宽,高),默认为(, )
@param img_type: 图片保存的格式,默认为GIF,可选的为GIF,JPEG,TIFF,PNG
@param mode: 图片模式,默认为RGB
@param bg_color: 背景颜色,默认为白色
@param fg_color: 前景色,验证码字符颜色,默认为蓝色#0000FF
@param font_size: 验证码字体大小
@param font_type: 验证码字体,默认为 ae_AlArabiya.ttf
@param length: 验证码字符个数
@param draw_lines: 是否划干扰线
@param n_lines: 干扰线的条数范围,格式元组,默认为(, ),只有draw_lines为True时有效
@param draw_points: 是否画干扰点
@param point_chance: 干扰点出现的概率,大小范围[, ]
@return: []: PIL Image实例
@return: []: 验证码图片中的字符串
'''
self.size=size
self.img_type=img_type
self.mode=mode
self.bg_color=bg_color
self.fg_color=fg_color
self.font_size = font_size
self.font_type =font_type
self.length = length
self.draw_lines =draw_lines
self.point_chance = point_chance
self.n_line=n_line
self.draw_points=draw_points
#执行初始化函数
self.getAllChar()
self.initPaint()
self.get_chars() def initPaint(self):
'''
初始画布
:return:
'''
self.width,self.height=self.size
self.img = Image.new(self.mode,self.size,self.bg_color)
self.draw = ImageDraw.Draw(self.img)#创建画笔 def getAllChar(self):
'''
获取所有字符串
:return:
'''
_letter_cases = "zxcvbnmasdfghjklqwertyuiop"
_upper_cases = _letter_cases.upper()
_numbers = ''.join(map(str, range(, )))
# 获取所有的字符
self.init_chars = ''.join((_letter_cases, _upper_cases, _numbers)) def get_chars(self):
'''生成给定长度的字符串,返回裂变格式'''
return random.sample(self.init_chars,self.length)#从给定字符串中获取出随机字符 def create_lines(self):
'''绘制干扰线'''
line_num = random.randint(*self.n_line)#从元组中获取线条数目
for i in range(line_num):
#起始点
begin = (random.randint(,self.size[]),random.randint(,self.size[]))#在图片中随机位置
end = (random.randint(,self.size[]),random.randint(,self.size[]))#在图片中随机位置
self.draw.line([begin,end],fill=(,,)) def create_point(self):
'''绘制干扰点'''
chance = min(,max(,int(self.point_chance)))#大小限制在point_chance到100
for w in range(self.width):
for h in range(self.height):
tmp = random.randint(,)
if tmp > -chance:
self.draw.point((w,h),fill=(,,)) def create_strs(self):
'''绘制验证码'''
c_chars = self.get_chars()
strs = ' %s '%' '.join(c_chars) font = ImageFont.truetype(self.font_type,self.font_size)
font_width,font_height = font.getsize(strs) self.draw.text(((self.width-font_width)/,(self.height-font_height)/),strs,font=font,fill=self.fg_color) return ''.join(c_chars) def get_img(self):
if self.draw_lines:
self.create_lines()
if self.draw_points:
self.create_point()
strs = self.create_strs()
# 图形扭曲参数
params = [ - float(random.randint(, )) / ,
,
,
,
- float(random.randint(, )) / ,
float(random.randint(, )) / ,
0.001,
float(random.randint(, )) /
]
img = self.img.transform(self.size, Image.PERSPECTIVE, params) # 创建扭曲 img = img.filter(ImageFilter.EDGE_ENHANCE_MORE) # 滤镜,边界加强(阈值更大) return img,strs if __name__=="__main__":
img= CreateCode()
image,code=img.get_img()
print(code)

在控制器中调用,并生成路由,在前端调用


from backend.utils.verifycode import CreateCode
class VerifyImgHandler(BaseRequestHandler):
def get(self):
Img = CreateCode(img_type="PNG")
img,code = Img.get_img()
self.session['code']=code
#StringIO操作的只能是str,如果要操作二进制数据,就需要使用BytesIO。
#BytesIO实现了在内存中读写bytes,我们创建一个BytesIO,然后写入一些bytes
mstream = io.BytesIO() # 创建一个BytesIO临时保存生成图片数据
img.save(mstream,"PNG")#将返回的验证码图片数据,添加到BytesIO临时保存 self.write(mstream.getvalue())#从BytesIO临时保存,获取图片返回给img的 src= 进行显示

路由添加:

(r"/getcode",AccountController.VerifyImgHandler)

前端代码:

    <div class="col-sm-4">
<img style="width: 100%;height: 100%" id="code" onclick="changeCode(this);" src="/getcode"/>
</div>
    function changeCode(ths){
var src =$(ths).attr("src")
arr = src.split("?")
src =arr[]+'?'+Math.random()
$(ths).attr("src",src)
}

函数模板使用:

#!/usr/bin/env python
# -*- coding:utf- -*- import random
from PIL import Image, ImageDraw, ImageFont, ImageFilter _letter_cases = "abcdefghjkmnpqrstuvwxy" # 小写字母,去除可能干扰的i,l,o,z
_upper_cases = _letter_cases.upper() # 大写字母
_numbers = ''.join(map(str, range(, ))) # 数字
init_chars = ''.join((_letter_cases, _upper_cases, _numbers)) def create_validate_code(size=(, ),
chars=init_chars,
img_type="GIF",
mode="RGB",
bg_color=(, , ),
fg_color=(, , ),
font_size=,
font_type="Monaco.ttf",
length=,
draw_lines=True,
n_line=(, ),
draw_points=True,
point_chance=):
"""
@todo: 生成验证码图片
@param size: 图片的大小,格式(宽,高),默认为(, )
@param chars: 允许的字符集合,格式字符串
@param img_type: 图片保存的格式,默认为GIF,可选的为GIF,JPEG,TIFF,PNG
@param mode: 图片模式,默认为RGB
@param bg_color: 背景颜色,默认为白色
@param fg_color: 前景色,验证码字符颜色,默认为蓝色#0000FF
@param font_size: 验证码字体大小
@param font_type: 验证码字体,默认为 ae_AlArabiya.ttf
@param length: 验证码字符个数
@param draw_lines: 是否划干扰线
@param n_lines: 干扰线的条数范围,格式元组,默认为(, ),只有draw_lines为True时有效
@param draw_points: 是否画干扰点
@param point_chance: 干扰点出现的概率,大小范围[, ]
@return: []: PIL Image实例
@return: []: 验证码图片中的字符串
""" width, height = size # 宽高
# 创建图形
img = Image.new(mode, size, bg_color)
draw = ImageDraw.Draw(img) # 创建画笔 def get_chars():
"""生成给定长度的字符串,返回列表格式"""
return random.sample(chars, length) def create_lines():
"""绘制干扰线"""
line_num = random.randint(*n_line) # 干扰线条数 for i in range(line_num):
# 起始点
begin = (random.randint(, size[]), random.randint(, size[]))
# 结束点
end = (random.randint(, size[]), random.randint(, size[]))
draw.line([begin, end], fill=(, , )) def create_points():
"""绘制干扰点"""
chance = min(, max(, int(point_chance))) # 大小限制在[, ] for w in range(width):
for h in range(height):
tmp = random.randint(, )
if tmp > - chance:
draw.point((w, h), fill=(, , )) def create_strs():
"""绘制验证码字符"""
c_chars = get_chars()
strs = ' %s ' % ' '.join(c_chars) # 每个字符前后以空格隔开 font = ImageFont.truetype(font_type, font_size)
font_width, font_height = font.getsize(strs) draw.text(((width - font_width) / , (height - font_height) / ),
strs, font=font, fill=fg_color) return ''.join(c_chars) if draw_lines:
create_lines()
if draw_points:
create_points()
strs = create_strs() # 图形扭曲参数
params = [ - float(random.randint(, )) / ,
,
,
,
- float(random.randint(, )) / ,
float(random.randint(, )) / ,
0.001,
float(random.randint(, )) /
]
img = img.transform(size, Image.PERSPECTIVE, params) # 创建扭曲 img = img.filter(ImageFilter.EDGE_ENHANCE_MORE) # 滤镜,边界加强(阈值更大) return img, strs

验证码纯函数

调用:

def check_code(req):
stream = BytesIO()  #获取内存块句柄,将数据保存在内存中
img,code = create_validate_code()
img.save(stream,'PNG')
req.session['check_code']=code.lower() return HttpResponse(stream.getvalue())  #获取内存中的数据,返回给页面

或者:

    f = open('1.png','wb')  #获取文件句柄,将数据保存在文件中
img,code = create_validate_code()
img.save(f,"PNG") #将图片二进制数据写入文件中

python---生成验证码图片的更多相关文章

  1. 纯代码系列:Python实现验证码图片(PIL库经典用法用法,爬虫12306思路)

    现在的网页中,为了防止机器人提交表单,图片验证码是很常见的应对手段之一.这里就不详细介绍了,相信大家都遇到过. 现在就给出用Python的PIL库实现验证码图片的代码.代码中有详细注释. #!/usr ...

  2. 第二百七十节,Tornado框架-生成验证码图片,以及验证码结合Session验证

    Tornado框架-生成验证码图片,以及验证码结合Session验证 第一.生成验证码图片  生成验证码图片需要两个必须模块 1.python自带的random(随机模块) 2.Pillow()图像处 ...

  3. java web学习总结(九) -------------------通过Servlet生成验证码图片

    一.BufferedImage类介绍 生成验证码图片主要用到了一个BufferedImage类,如下:

  4. JavaWeb---总结(九)通过Servlet生成验证码图片

    一.BufferedImage类介绍 生成验证码图片主要用到了一个BufferedImage类,如下: 创建一个DrawImage Servlet,用来生成验证码图片  1 package gacl. ...

  5. Java 生成验证码图片

    生成验证码图片并对提交的输入进行验证 // HttpServletResponse常见应用——生成验证码 // 利用BufferedImage类生产随机图片 public static final i ...

  6. javaweb学习总结(九)—— 通过Servlet生成验证码图片

    一.BufferedImage类介绍 生成验证码图片主要用到了一个BufferedImage类,如下:

  7. 012. asp.net生成验证码图片(汉字示例/字母+数字)

    protected void Page_Load(object sender, EventArgs e) { //生成验证码图片的基本步骤 string checkCode = "新年快乐& ...

  8. J2EE如何生成验证码图片和点击刷新验证码

    验证码图片生成步骤 创建BufferedImage对象. 获取BufferedImage的画笔,即调用getGraphics()方法获取Graphics对象. 调用Graphics对象的setColo ...

  9. java web 学习九(通过servlet生成验证码图片)

    一.BufferedImage类介绍 生成验证码图片主要用到了一个BufferedImage类,如下:

  10. java web,生成验证码图片的技术

    偶然知道原来有些网站的验证码图片都是随机生成的,后来听人讲了一下,就做了这个小例子 生成图片,绘制背景,数字,干扰线用到了java.awt包,主要使用BufferedImage来生成图片,然后使用Gr ...

随机推荐

  1. [转] Linux有问必答:如何修复“sshd error: could not load host key”

    编译自:http://ask.xmodulo.com/sshd-error-could-not-load-host-key.html作者: GOLinux 本文地址:https://linux.cn/ ...

  2. JavaScript 作用域链与闭包

    作用域链 在某个作用域访问某个变量或者函数时,会首先在自己的局部环境作用域中搜寻变量或者函数,如果本地局部环境作用域中有该变量或者函数,则就直接使用找到的这个变量值或者函数:如果本地局部环境作用域中没 ...

  3. PAT 1081 检查密码

    https://pintia.cn/problem-sets/994805260223102976/problems/994805261217153024 本题要求你帮助某网站的用户注册模块写一个密码 ...

  4. TDD中测试替身学习总结

    在使用TDD开发时,经常会遇到需要被测对象需要依赖其他子系统的情况,但是你希望将测试代码跟依赖项隔离,以保证测试代码仅仅针对当前被测对象或方法展开,这时候你需要的是测试替身.测试替身可以分为四类:- ...

  5. vue的自定义组件和组件传值

    <div id="app"> <div>{{pmessage}}</div> //父组件 <child :message="pm ...

  6. Oracle 和 SQLSERVER 重新获取统计信息的方法

    1. Oracle 重新获取统计信息的命令 exec dbms_stats.gather_schema_stats(ownname =>) # 需要修改 ownername options 指定 ...

  7. CSS 范围选择器(自编)

    选择第一个到第六个li元素ul li:nth-child(n+3):not(:nth-child(n+6)){} 选择第二个到最后一个ul li:nth-child(2)~li{} 选择除了第一个和最 ...

  8. BZOJ1124 POI2008枪战Maf(环套树+贪心)

    每个点出度都为1,可以发现这张图其实是个环套树森林,树中儿子指向父亲,环上边同向. 首先自环肯定是没救的,先抬出去. 要使死亡人数最多的话,显然若一个点入度为0其不会死亡,而一个孤立的环至少会留下一个 ...

  9. day24 新三级菜单

    china = { "shandong":{ "linyi":["lanshan","nanfang","he ...

  10. java web项目406错误的解决

    返回的消息头浏览器不能解释 这里我们使用了@ResponseBody,返回数据后缀是,.json,但是我们的映射器后缀又是.html.最后浏览器收到数据不知该以哪种类型数据来进行解析,所以就会报406 ...