python---生成验证码图片
工具插件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---生成验证码图片的更多相关文章
- 纯代码系列:Python实现验证码图片(PIL库经典用法用法,爬虫12306思路)
现在的网页中,为了防止机器人提交表单,图片验证码是很常见的应对手段之一.这里就不详细介绍了,相信大家都遇到过. 现在就给出用Python的PIL库实现验证码图片的代码.代码中有详细注释. #!/usr ...
- 第二百七十节,Tornado框架-生成验证码图片,以及验证码结合Session验证
Tornado框架-生成验证码图片,以及验证码结合Session验证 第一.生成验证码图片 生成验证码图片需要两个必须模块 1.python自带的random(随机模块) 2.Pillow()图像处 ...
- java web学习总结(九) -------------------通过Servlet生成验证码图片
一.BufferedImage类介绍 生成验证码图片主要用到了一个BufferedImage类,如下:
- JavaWeb---总结(九)通过Servlet生成验证码图片
一.BufferedImage类介绍 生成验证码图片主要用到了一个BufferedImage类,如下: 创建一个DrawImage Servlet,用来生成验证码图片 1 package gacl. ...
- Java 生成验证码图片
生成验证码图片并对提交的输入进行验证 // HttpServletResponse常见应用——生成验证码 // 利用BufferedImage类生产随机图片 public static final i ...
- javaweb学习总结(九)—— 通过Servlet生成验证码图片
一.BufferedImage类介绍 生成验证码图片主要用到了一个BufferedImage类,如下:
- 012. asp.net生成验证码图片(汉字示例/字母+数字)
protected void Page_Load(object sender, EventArgs e) { //生成验证码图片的基本步骤 string checkCode = "新年快乐& ...
- J2EE如何生成验证码图片和点击刷新验证码
验证码图片生成步骤 创建BufferedImage对象. 获取BufferedImage的画笔,即调用getGraphics()方法获取Graphics对象. 调用Graphics对象的setColo ...
- java web 学习九(通过servlet生成验证码图片)
一.BufferedImage类介绍 生成验证码图片主要用到了一个BufferedImage类,如下:
- java web,生成验证码图片的技术
偶然知道原来有些网站的验证码图片都是随机生成的,后来听人讲了一下,就做了这个小例子 生成图片,绘制背景,数字,干扰线用到了java.awt包,主要使用BufferedImage来生成图片,然后使用Gr ...
随机推荐
- 安装phpredis扩展
本文是根据菜鸟教程中的内容而写的,因为按照教程中做法来操作,中间遇到一些问题,我在centos6.5和ubuntu16.4中都遇到了,所以写在这里.强烈建议你先看完这篇博客,然后再操作,能省不少事. ...
- Selenium vs TestStudio,Selenium Grid vs F2Test
Selenium vs TestStudio,不知道差异在哪里? Selenium Grid vs F2Test,后者更优. 用Selenium + FireFox做了一个单机抓图,想要扩展成集群的话 ...
- postman发送json格式的post请求
在地址栏里输入请求url:http://127.0.0.1:8081/getmoney 选择“POST”方式, 在“headers”添加key:Content-Type , value:applic ...
- [转帖]TMD为你揭秘中国互联网下半场所有秘密
https://www.iyiou.com/p/35099.html 李安说,<比利.林恩的中场战事>是“一个成长的故事”.中国互联网也行至中场,下半场如何走,成长的方向在哪里,成当下关键 ...
- Oracle重新获取统计信息以及SQLSERVER重建索引
Oracle重新获取统计信息 exec dbms_stats.gather_schema_stats(ownname =>'LCoe739999',options => 'GATHER', ...
- Qt__事件处理机制
一.Qt事件 Qt会将系统消息(如鼠标按键.键盘按键等)转化为Qt事件,Qt事件被封装为对象且定义该对象的类均继承自抽象类QEvent. 二.Qt事件的产生 1.操作系统产生 Spontaneous ...
- html 佈局
html常見佈局方式有以下幾種: 1.使用div的html 利用div可以為html實現多列佈局. 2.使用html5的網站佈局, 利用html新增的header.footer.nav.section ...
- windows编程按小时生成日志文件
这是一个简单的日志记录方法,为了避免单个日志文件过大,所以每个小时生成一个新的日志文件 注意:g_pLogPath 可以带路径,但是必须手动创建好路径,保证目录存在.而且要详细到log文件名,不能带后 ...
- ansible系列5-开启加速 Ansible 执行速度的功能
SSH pipelining 是一个加速 Ansible 执行速度的简单方法.ssh pipelining 默认是关闭,之所以默认关闭是为了兼容不同的 sudo 配置,主要是 requiretty 选 ...
- MarkdownPad 注册码 Version 2.5.0.27920
[注册码] 还望多多支持正版 邮箱地址: Soar360@live.com 授权秘钥: GBPduHjWfJU1mZqcPM3BikjYKF6xKhlKIys3i1MU2eJHqWGImDHzWdD6 ...