In today's web pages, image verification codes are one of the most common ways to prevent bots from submitting forms. Here is not detailed introduction, I believe we have met.
Now give the code to implement the CAPTCHA image using Python's PiL library. Detailed comments are in the code.
#!/usr/bin/env python#coding=utf-8import randomfrom PIL import Image, Imagedraw, imagefont, imagefilter_letter_cases = " Abcdefghjkmnpqrstuvwxy "# lowercase letters, removing potentially disturbing i,l,o,z_upper_cases = _letter_cases.upper () # uppercase letters _numbers = '. Join (Map (str, Range (3, 10)) # number Init_chars = '. Join ((_letter_cases, _upper_cases, _numbers) def create_validate_code (size= (120, 30) , Chars=init_chars, img_type= "GIF", mode= "RGB", Bg_color= (255, 255, 255), fg_color= (0, 0, 255), font _size=18, font_type= "Ae_alarabiya.ttf", length=4, Draw_lines=true, n_line= (1, 2), Draw_points=true, Point_chance = 2): "@todo: Generate CAPTCHA image @param size: size of picture, format (wide, high), default to (+), @param chars: Allowed character set, format string @ Param img_type: Picture saved format, default GIF, optional forGif,jpeg,tiff,png @param mode: Picture mode, default is RGB @param bg_color: Background color, default is white @param fg_color: foreground color, captcha character color, default is blue #0000ff @param font_size: captcha font size @param font_type: Captcha font, default is Ae_alarabiya.ttf @param length: Number of captcha characters @param draw_line S: whether to draw the interference line @param N_lines: The number range of interference lines, the format tuple, the default is (1, 2), only Draw_lines is true when valid @param draw_points: whether to draw the interference point @param point_ch ance: Probability of occurrence of interference points, size range [0] @return: [0]: PIL image instance @return: [1]: Captcha image in the string ' width, height = size # width, height img = image.new (mode, size, bg_color) # Create graphic draw = Imagedraw.draw (img) # Create a Brush def get_chars (): "' Generate a given length The string that returns the list format ' return random.sample (chars, length) def create_lines (): ' Draw the interfering line ' ' Line_num = Rand Om.randint (*n_line) # Number of interfering lines for I in range (Line_num): # starting point begin = (Random.randint (0, Size[0 ]), Random.randint (0, size[1]) #结束点 end = (Random.randint (0, size[0]), Random.randint (0, size[1])) Draw.line ([BeGin, end], fill= (0, 0, 0)) def create_points (): ' Draw disturbance point ' ' chance = min (+, max (0, Int (point_chance))) # size limit at [0, +] for W in xrange (width): for h in xrange (height): tmp = Random.rand Int (0, +) if tmp > 100-chance:draw.point ((w, h), fill= (0, 0, 0)) def create_s TRS (): ' Draw Authenticode character ' ' C_chars = Get_chars () STRs = '%s '% '. Join (C_chars) # Each character is separated by a space Font = Imagefont.truetype (Font_type, font_size) font_width, font_height = Font.getsize (STRs) Draw.text (( (width-font_width)/3, (Height-font_height)/3), STRs, Font=font, Fill=fg_color) re Turn '. Join (C_chars) if Draw_lines:create_lines () if draw_points:create_points () STRs = create_s TRS () # graphics Twist parameter params = [1-float (Random.randint (1, 2))/100, 0, 0, 0, 1-float (RandoM.randint (1,))/1, Float (Random.randint (, 2))/, 0.001, float (random.ran Dint (1, 2)/+] img = img.transform (size, image.perspective, params) # Create twist img = Img.filter (imagef Ilter. Edge_enhance_more) # Filter, Edge Enhancement (threshold value) return img, strsif __name__ = = "__main__": code_img = Create_validate_code () c Ode_img.save ("Validate.gif", "gif")
The final result returns a tuple, the first return value is an instance of the image class, and the second argument is the string in the picture (the effect of the comparison is correct).
Note that if you throw an IOError exception when generating an Imagefont.truetype instance, it is possible that the computer running the code does not contain the specified font and needs to be downloaded and installed.
Generated captcha picture effect:
At this time, the careful classmate may ask, if each generation of verification code, you must first save the generated picture, and then display to the page. It is unacceptable to do so. At this point, we need to use Python's built-in Stringio module, which behaves like a file object, but it operates on a memory file. So we can write the code like this:
try: import cStringIO as StringIOexcept ImportError: import StringIOmstream = StringIO.StringIO()
This way, we need to use "mstream.getvalue ()" When we want to output the image. In Django, for example, we first define a URL like this:
from django.conf.urls.defaults import *urlpatterns = patterns(‘example.views‘, url(r‘^validate/$‘, ‘validate‘, name=‘validate‘),)
In views, we save the correct string in the session so that when the user submits the form, it can be compared with the correct string in the session.
from django.shortcuts import HttpResponsefrom validate import create_validate_codedef validate(request): mstream = StringIO.StringIO() validate_code = create_validate_code() img = validate_code[0] img.save(mstream, "GIF") request.session[‘validate‘] = validate_code[1] return HttpResponse(mstream.getvalue(), "image/gif")
Pure Code Series: Python Implementation captcha picture (PIL Library Classic usage, crawler 12306 ideas)