引入

基本上大家使用每一种网络服务都会遇到验证码,一般是网站为了防止恶意注册、发帖而设置的验证手段。其生成原理是将一串随机产生的数字或符号,生成一幅图片,图片里加上一些干扰象素(防止OCR)。下面就详细讲解如何生成验证码。

所需环境

除了配置好的python环境外,还需要配有python中的PIL库,这是python中专门用来处理图片的库。用传统的pip install 方法或者下载源码 python setup.py install 方法安装该库,很可能会报错(视运行环境不同)。可以采用以下方法

123456 1.下载安装包URLhttp://www.pythonware.com/products/pil/index.htm,要下载支持全平台的。2.解压缩: tar zxv f Imaging1.1.7.tar.gz3.进入到解压后的目录: cd Imaging1.1.74.Bulid pakagepython setup.py build_ext i5.测试:python selftest.py6.安装:python setup.py install

代码实现

要生成验证码图片,我们首先要生成一个随机字符串,包含26个字母和10个数字。

123456 #用来随机生成一个字符串def gene_text():    source = list(string.letters)    for index in range(0,10):        source.append(str(index))    return \’\’.join(random.sample(source,number))#number是生成验证码的位数

然后我们要创建一个图片,写入字符串,需要说明的这里面的字体是不同系统而定,如果没有找到系统字体路径的话,也可以不设置

123456789 def gene_code():    width,height = size #宽和高    image = Image.new(\’RGBA\’,(width,height),bgcolor) #创建图片    font = ImageFont.truetype(font_path,25) #验证码的字体和字体大小    draw = ImageDraw.Draw(image)  #创建画笔    text = gene_text() #生成字符串    font_width, font_height = font.getsize(text)    draw.text(((width font_width) / number, (height font_height) / number),text,            font= font,fill=fontcolor) #填充字符串

接下来,我们要在图片上画几条干扰线

12345 #用来绘制干扰线def gene_line(draw,width,height):    begin = (random.randint(0, width), random.randint(0, height))    end = (random.randint(0, width), random.randint(0, height))    draw.line([begin, end], fill = linecolor)

最后创建扭曲,加上滤镜,用来增强验证码的效果。

123     image = image.transform((width+20,height+10), Image.AFFINE, (1,0.3,0,0.1,1,0),Image.BILINEAR)  #创建扭曲    image = image.filter(ImageFilter.EDGE_ENHANCE_MORE) #滤镜,边界加强    image.save(\’idencode.png\’) #保存验证码图片

下面是用上述程序生成的一个验证码

下面是完整的代码:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 #coding=utf-8import randomimport stringimport sysimport mathfrom PIL import Image,ImageDraw,ImageFont,ImageFilter #字体的位置,不同版本的系统会有不同font_path = \’/Library/Fonts/Arial.ttf\’#生成几位数的验证码number = 4#生成验证码图片的高度和宽度size = (100,30)#背景颜色,默认为白色bgcolor = (255,255,255)#字体颜色,默认为蓝色fontcolor = (0,0,255)#干扰线颜色。默认为红色linecolor = (255,0,0)#是否要加入干扰线draw_line = True#加入干扰线条数的上下限line_number = (1,5) #用来随机生成一个字符串def gene_text():    source = list(string.letters)    for index in range(0,10):        source.append(str(index))    return \’\’.join(random.sample(source,number))#number是生成验证码的位数#用来绘制干扰线def gene_line(draw,width,height):    begin = (random.randint(0, width), random.randint(0, height))    end = (random.randint(0, width), random.randint(0, height))    draw.line([begin, end], fill = linecolor) #生成验证码def gene_code():    width,height = size #宽和高    image = Image.new(\’RGBA\’,(width,height),bgcolor) #创建图片    font = ImageFont.truetype(font_path,25) #验证码的字体    draw = ImageDraw.Draw(image)  #创建画笔    text = gene_text() #生成字符串    font_width, font_height = font.getsize(text)    draw.text(((width font_width) / number, (height font_height) / number),text,            font= font,fill=fontcolor) #填充字符串    if draw_line:        gene_line(draw,width,height)    # image = image.transform((width+30,height+10), Image.AFFINE, (1,-0.3,0,-0.1,1,0),Image.BILINEAR)  #创建扭曲    image = image.transform((width+20,height+10), Image.AFFINE, (1,0.3,0,0.1,1,0),Image.BILINEAR)  #创建扭曲    image = image.filter(ImageFilter.EDGE_ENHANCE_MORE) #滤镜,边界加强    image.save(\’idencode.png\’) #保存验证码图片if __name__ == \”__main__\”:    gene_code()