Python生成图片验证码的完整实现方案

顾言
顾言
发布时间:2026-10-13 | 4人浏览过
原创

本文提供基于Python PIL库的图片验证码生成代码,旨在通过图形验证阻止机器人自动注册。代码支持自定义字符集、图片尺寸、字体及干扰元素,生成包含随机字符串的图片,适用于Web开发中的用户身份验证环节。

Python图片验证码生成代码详解

以下展示一个实际应用的验证码生成示例。


复制代码

具体实现代码如下:


#coding: utf-8


import Image,ImageDraw,ImageFont,os,string,random,ImageFilter


def initChars():


"""

定义允许的字符集合,初始包含数字、大写及小写字母。


用法: initChars()


参数: 无


返回: 列表


返回可用的字符集列表。


用途: 用于picChecker类的初始化字符集合。


待办: 无


"""

nums = [str(i) for i in range(10)]


letterCase = [


'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',


'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',


'w', 'x', 'y', 'z'


]

upperCase = [


'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',


'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',


'W', 'X', 'Y', 'Z',


]

return(nums+letterCase+upperCase)


class picChecker():


"""

图片验证码生成类:


1) 在用户注册时要求填写图片验证码,以有效阻止机器人批量注册。


2) 生成的图片验证码字符数固定为 4 位(包含大小写字母与数字,且不区分大小写)。


若用户未填写验证码或填写错误,


页面将友好提示用户重新填写(同时程序端也会进行相应限制)。


用法: pc = picChecker().createChecker()


参数: 包含多项配置,详见下方


chars 允许的字符集合,


类型 list


默认值 initChars()


示例 ['1','2','3']


length 字符串长度


类型 integer


默认值 4


size 图片大小


类型 tuple


默认值 (120,30)


示例 (120,30)


fontsize 字体大小


类型 integer


默认值 25


begin 字符起始位置,即左上角坐标


类型 tuple


默认值 (5,-2)


outputType 输出类型


类型 string


默认值 GIF


可选值 GIF JPEG TIFF PNG


mode 图片模式


类型 string


可选值 RGB L (推荐仅使用这两种)


默认值 RGB


backgroundColor 背景色


foregroundColor 前景色


当mode=RGB时,backgroundColor,foregroundColor为tuple类型


取值为(integer,integer,integer)


表示RGB颜色值


当mode=L时,backgroundColor,foregroundColor为数字,表示黑白模式


取值为0-255


表示灰度值


fonttype 字体路径


类型 string


默认值 "simsum.ttc"


jamNum 干扰线条数


类型 (int1,int1)


int1 干扰线条数下限,包含该值


int2 干扰线条数上限,包含该值


pointBorder 散点噪音


构造方法:对每个像素点使用随机函数判断是否在该像素上绘制散点噪音。


类型 (int1,int2)


int1数值越大 散点越多


int2数值越大 散点越少


返回: [picCheckerStr,pic]


picCheckerStr: 表示返回图片中对应的字符串,可用于session验证以及其他用途


pic : 返回的图片,类型为Image


用途:


待办: 无


"""

#默认字体路径


#DEFAULT_FONT_PATH = os.path.join(os.path.dirname(__file__),'simsun.ttc').replace('\\','/')


def __init__(self,chars = initChars(),size = (120,30),fontsize = 25,


begin = (5,-2),outputType = 'GIF',mode = 'RGB' ,


backgroundColor = (255,255,255), foregroundColor = (0,0,255),


fonttype = "simsun.ttc",length = 4,jamNum = (1,2),


pointBorder = (40,39)):


"""

初始化配置参数


"""

#验证码配置


#允许的字符串集合


self.chars = chars


#图片大小


self.size = size


#字符起始插入点


self.begin = begin


#字符串长度


self.length = length


#输出类型


self.outputType = outputType


#字符大小


self.fontsize = fontsize


#图片模式


self.mode = mode


#背景色


self.backgroundColor = backgroundColor


#前景色


self.foregroundColor = foregroundColor


#干扰线条数


self.jamNum = jamNum


#散点噪音界限


self.pointBorder = pointBorder


#字体库路径


self.fonttype = fonttype


#设置字体,大小默认为18


self.font = ImageFont.truetype(self.fonttype, self.fontsize)


def getPicString(self):


"""

用法: getPicString()


返回: string


用途: 生成给定长度的随机字符串


待办: 无


"""

#初始化字符串长度


length = self.length


#初始化字符集合


chars = self.chars


#获得字符集合


selectedChars = random.sample(chars,length)


charsToStr = string.join(selectedChars,'')


return(charsToStr)


def createChecker(self):


"""

用法: createChecker()


返回: [str,pic]


str:对应的字符串


pic:对应的图片


用途:


待办:


"""

#获得验证码字符串


randStr = self.getPicString()


#将字符串加入空格


randStr1 = string.join([i+" " for i in randStr],"")


#创建图形


im = Image.new(self.mode,self.size,self.backgroundColor)


#创建画笔


draw = ImageDraw.Draw(im)


#输出随机文本


draw.text(self.begin, randStr1, font=self.font,fill=self.foregroundColor)


#im = self.drawText(draw,randStr,im)


#干扰线


self.createJam(draw)


#散点噪音


self.createPoints(draw)


#图形扭曲


para = [1-float(random.randint(1,2))/100,


0,


0,


0,


1-float(random.randint(1,10))/100,


float(random.randint(1,2))/500,


0.001,


float(random.randint(1,2))/500


]

#print randStr,para


im = im.transform(im.size, Image.PERSPECTIVE,para)


#图像滤镜


im=im.filter(ImageFilter.EDGE_ENHANCE_MORE)


im.save("checker.jpg",self.outputType)


return([randStr,im])


def createJam(self,draw):


"""

用法: 创建干扰线


参数: draw 表示画笔


返回: None


用途:


待办:


"""

#干扰线条数


lineNum = random.randint(self.jamNum[0],self.jamNum[1])


for i in range(lineNum):


begin = (random.randint(0,self.size[0]),random.randint(0,self.size[1]))


end = (random.randint(0,self.size[0]),random.randint(0,self.size[1]))


draw.line([begin,end],fill = (0,0,0))


def createPoints(self,draw):


"""

用法: 创建散点噪音


参数: draw 表示画笔


返回: None


用途:


待办:


"""

#散点噪音


for x in range(self.size[0]):


for y in range(self.size[1]):


flag = random.randint(0,self.pointBorder[0])


if flag > self.pointBorder[1]:


draw.point((x,y),fill = (0,0,0))


del flag


if __name__ == '__main__':


c=picChecker()


t=c.createChecker()


print(t)


相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表