这周一我写了一篇文章《2000字谏言,给那些想学Python的人,建议收藏后细看!》,告诉你如何快速学习python。这其中就是为什么我们不应该执着于调用框架和模块,而是先造轮子。然后今天为你做一个。验证码是web开发中不可或缺的元素,python提供了很多验证码模块帮助你快速生成各种验证码。你知道验证码生成的原理吗?所谓知其然,亦知其所以然。面试的时候,面试官不会因为你熟悉框架就表扬你。今天小胖就给大家层层展示验证码的外衣,看看其中的小玄机-<-demo环境操作系统:windows10python版本:python3.7代码编辑器:pycharm2018.2使用第三方模块:pillowverification代码必备要素一张图片文字干扰元素线条干扰小圆点干扰熟悉枕头库既然我们需要使用枕头库来制作验证码,那么首先我们来熟悉一下我们需要使用的方法。Image.new():这个方法可以生成一个图像,有三个参数。mode:颜色空间模式,可以是'RGBA'、'RGB'、'L'等modesize:图像大小,接收两个整数的原始祖先color:图像的填充颜色,可以是红色、绿色,等等,or是rgb这三个整数的祖先。即背景色fromPILimportImagecaptcha=Image.new('RGB',(1080,900),(255,255,255))以上代码创建了1亿RGB的色彩空间模式,大小为1080*900,并且背景颜色为白色图片。Image.save():保存图片到本地fp:本地文件名格式:可选参数,指定文件扩展名。fromPILimportImagecaptcha=Image.new('RGB',(1080,900),(255,255,255))#captcha.save('captcha.png')captcha.save('captcha',format='png')以上两种方式保存的效果是一样的。Image.show():显示图片,会调用电脑自带的显示图片的软件。ImageFont.truetype():加载一个字体文件。生成字体对象。fromPILimportImageFont#字体文件路径字体大小font=ImageFont.truetype('simkai.ttf',16)ImageDraw.Draw():生成画笔对象。fromPILimportImage,ImageDrawcaptcha=Image.new('RGB',(1080,900),'red')draw=ImageDraw.Draw(captcha)上面在验证码图片上创建了一个画笔,我们在这个上面画了什么图像将使用此画笔对象。ImageDraw.Draw().text():在图像上绘制给定的字符fromPILimportImage,ImageDraw,ImageFontcaptcha=Image.new('RGB',(1080,900),'red')font=ImageFont.truetype('simkai.ttf',16)draw=ImageDraw.Draw(captcha)#在绘制字符的位置绘制字符,定义字体字符颜色draw.text((0,0),'helloworld',font=font,fill='black')ImageDraw.Draw().line():在图片上画线条fromPILimportImage,ImageDraw,ImageFontcaptcha=Image.new('RGB',(1080,900),'red')draw=ImageDraw.Draw(captcha)#直线的起点和直线的终点draw.line([(0,0),(1080,900)],fill='black')ImageDraw.Draw().point():在图片上画一个点fromPILimportImage,ImageDraw,ImageFontcaptcha=Image.new('RGB',(1080,900),'red')font=ImageFont.truetype('simkai.ttf',16)draw=ImageDraw.Draw(captcha)#positionofthepointColordraw.point((500,500),fill='black')制作我们的验证码,我们就用上面的方法。当然,pillow的方法肯定不止这些,我们这里只罗列一下。制作验证码,首先我们定义一个类,并初始化一些需要的参数。importstringclassCaptcha():'''captcha_size:验证码图像大小font_size:字体大小text_number:验证码中的字符数line_number:行数background_color:验证码来源的背景颜色:示例字符集。验证码中的字符是从这个save_format中随机选择的:Captchasaveformat'''def__init__(self,captcha_size=(150,100),font_size=30,text_number=4,line_number=4,background_color=(255,255,255),sources=None,save_format='png'):self.text_number=text_numberself.line_number=line_numberself.captcha_size=captcha_sizeself.background_color=background_colorself.font_size=font_sizeself.format=save_formatifself.sources:sources=sourceselse:self.sources=string.ascii_letters+string.digits这里先说string模块。string.ascii_letters:从a-zA-Z中获取所有字符string.digits:从0-9中获取所有数字从源中随机获取字符importrandomdefget_text(self):text=random.sample(self.sources,k=self.text_number)return''.join(text)random.sample()方法:从第一个参数中获取随机字符。采集次数由第二个参数指定。随机获取绘制字符的颜色defget_font_color(self):font_color=(random.randint(0,150),random.randint(0,150),random.randint(0,150))returnfont_color随机获取的颜色干扰线defget_line_color(self):line_color=(random.randint(0,250),random.randint(0,255),random.randint(0,250))returnline_color书写和绘制文本的方法defdraw_text(self,draw,text,font,captcha_width,captcha_height,spacing=20):'''绘制图片上传入的字符:paramdraw:画笔对象:paramtext:绘制的所有字符:paramfont:fontobject:paramcaptcha_width:verificationcodeWidth:paramcaptcha_height:验证码高度:paramspacing:每个字符的间距:return:'''#得到这个字符的高度和宽度text_width,text_height=font.getsize(text)#得到每个字体的大概宽度ofevery_value_width=int(text_width/4)#这个字符的总长度text_length=len(text)#中间有一个空隙n每两个字符,得到总间距total_spacing=(text_length-1)*spacingiftotal_spacing+text_width>=captcha_width:raiseValueError("字体加上中间间距超过图片宽度!")#得到第一个字符绘制位置start_width=int((captcha_width-text_width-total_spacing)/2)start_height=int((captcha_height-text_height)/2)#依次为文本中的值绘制每个字符:position=start_width,start_heightprint(position)#绘制文本draw.text(position),value,font=font,fill=self.get_font_color())#改变下一个字符的开始绘制位置'画线:paramdraw:画笔对象:paramcaptcha_width:验证码宽度:paramcaptcha_height:验证码高度:return:'''#随机获取起始位置坐标begin=(random.randint(0,captcha_width/2),random.randint(0,captcha_height))#随机获取结束位置坐标end=(random.randint(captcha_width/2,captcha_width),random.randint(0,captcha_height))draw.line([begin,end],fill=self.get_line_color())绘制小点defdraw_point(self,draw,pointt_chance,width,height):'''画点:paramdraw:brushobject:parampoint_chance:绘制小圆点的概率为point_chance/100:paramwidth:验证码width:paramheight:验证码高度:return:'''#根据概率随机绘制小圆点forwinrange(width):forhinrange(height):tmp=random.randint(0,100)iftmp
