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 ...
随机推荐
- Practice2 结对子之“小学四则运算”
开发环境:Eclipse,js,css,html 程序完成的方向: 1.可以出表达式里含有负整数(负整数最小不小于-100)的题目,且负数需要带括号,用户输入的结果不用带括号.如: 2*(-4) = ...
- 在XShell中使用sz和rz命令下载和上传文件
借助XShell,使用linux命令sz可以很方便的将服务器上的文件下载到本地,使用rz命令则是把本地文件上传到服务器 工具/原料 XShell CentOS 6.5 使用sz下载文件 1 输 ...
- TDD中测试替身学习总结
在使用TDD开发时,经常会遇到需要被测对象需要依赖其他子系统的情况,但是你希望将测试代码跟依赖项隔离,以保证测试代码仅仅针对当前被测对象或方法展开,这时候你需要的是测试替身.测试替身可以分为四类:- ...
- 使用docker-compose 大杀器来部署服务
使用docker-compose 大杀器来部署服务 上 我们都听过或者用过 docker,然而使用方式却是仅仅用手动的方式,这样去操作 docker 还是很原始. 好吧,可能在小白的眼中噼里啪啦的对着 ...
- [日常工作]WorkStation 使用端口转发的方式使用宿主机IP地址提供服务
1. 虚拟机内的地址如果经常变化,或者是想使用宿主机进行网络服务 但是又不想有人能够访问具体的服务器提供机器.. 可以使用宿主机转发虚拟机的端口的方式来进行处理. workstation 比较好实现 ...
- __new__ __init__区别
1 class A(object): 2 def __init__(self,*args, **kwargs): 3 print "init A" 4 def __new__(cl ...
- python学习笔记三——控制语句
2.5 运算符与表达式 2.5.1 算术运算符和算术表达式 算术运算符包括四则运算符.求模运算符和求幂运算符. 算术运算符 加减乘除:+ - * / 表达式:x+y x-y x*y x/y ...
- BZOJ2178 圆的面积并(simpson积分)
板子题.可以转一下坐标防止被卡.精度和常数实在难以平衡. #include<iostream> #include<cstdio> #include<cmath> # ...
- hdu1176 (免费馅饼)
免费馅饼 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- day6 笔记
元祖 只读不可取的列表,数据不能被修改 a = (20,30) 格式同列表,只是[] 换成了 () ps:元祖在创建的时候,最好在最后的元素后面加一个逗号,比如a = ( 20,) 用法类似于列表:切 ...