工具插件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. CSS里Postion几个取值relative、absolute、static、fixed的区别和用法

    ---恢复内容开始--- static:静态定位,也是postion的默认值,没有定位,元素出现在正常的流中,忽略top\bottom\left\right或者z-index声明. relative: ...

  2. PHP预防跨站脚本(XSS)攻击且不影响html代码显示效果

    什么是XSS 跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS.恶意攻击者往 ...

  3. PAT L3-021 神坛

    https://pintia.cn/problem-sets/994805046380707840/problems/994805046577840128 在古老的迈瑞城,巍然屹立着 n 块神石.长老 ...

  4. 使用highlightjs自定义markdown代码高亮

    目录 概述 实现方法 概述 最近使用markdown来写一些技术文档和博客,觉得真心不错,这才是程序员该用的编辑器嘛~~ Mou在mac上的 markdown 编辑器,很简约,可惜Mou好像只支持标准 ...

  5. Get请求,Post请求乱码问题解决方案

    下面以两种常见的请求方式为例讲解乱码问题的解决方法. 1.Post方式请求乱码. 自从Tomcat5.x以来,Get方式和Post方式提交的请求,tomcat会采用不同的方式来处理编码. 对于Post ...

  6. 时空CLR解密登陆密码源码

    public static SqlString GetPwd(string code ) { string txt = code; if(string.IsNullOrEmpty(txt)) { re ...

  7. ERP开源框架 + 二次开发平台 介绍

    经历了多年软件开发,深受网络大侠们的资源共享才得以有所成绩, 本人主要是做企业ERP软件,一直有个感受,开发具体某个功能不难,但随着需求的增加,管理庞大的代码却成了最大的问题 而为企业管理所做的开发, ...

  8. matplotlib之随机漫步

    # 随机漫步类 from random import choice from matplotlib import pyplot as plt from pylab import mpl from ma ...

  9. Bootstrap辅助类

    前面的话 Bootstrap提供了一组工具类,用于辅助项目的开发.本文将详细介绍Bootstrap辅助类 文本色 通过颜色来展示意图,Bootstrap 提供了一组工具类.这些类可以应用于链接,并且在 ...

  10. 嵌入式启动jetty

    由于jetty8以上版本已经抛弃JDK1.6,公司统一开发JDK又一直不升级,所以我们使用jetty8 pom.xml <project xmlns="http://maven.apa ...