Changeset 671

Show
Ignore:
Timestamp:
11/29/06 11:37:05
Author:
crchemist
Message:

Added new captcha generation engine.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • qPloneCaptchas/trunk/utils.py

    r670 r671  
    2222    import ImageDraw 
    2323    import ImageFilter 
     24    import random, math 
    2425    from PIL import ImageFile as pyImageFile 
    2526    import sys 
    2627    sys.modules['ImageFile'] = pyImageFile 
    2728    from cStringIO import StringIO 
     29 
     30    amplitude = random.uniform(3, 6.5)  
     31    period = random.uniform(0.04, 0.1) 
     32    offset = (random.uniform(0, math.pi * 2 / period), 
     33              random.uniform(0, math.pi * 2 / period)) 
     34 
     35    def getTransform(image): 
     36        return (lambda x, y, 
     37                a = amplitude, 
     38                p = period, 
     39                o = offset: 
     40                (math.sin( (y+o[0])*p )*a + x, 
     41                 math.sin( (x+o[1])*p )*a + y)) 
     42 
    2843    outFile = StringIO() 
    2944 
     
    3146    FONT_PATH = DATA_PATH + '/fonts' 
    3247 
    33     # randomly select the foreground color 
    34     fgcolor = randint(0x000000,0x000fff) 
    35     # make the background color the opposite of fgcolor 
    36     bgcolor = fgcolor ^ 0xffffff 
    37     # create a font object 
    38     import sys 
    39     font = ImageFont.truetype(FONT_PATH+'/vera/Vera.ttf', fnt_sz) 
    40     # determine dimensions of the text 
    41     dim = font.getsize(text) 
    42     # create a new image slightly larger that the text 
    43     im = Image.new('RGB', (dim[0]+5,dim[1]+5), bgcolor) 
    44     d = ImageDraw.Draw(im) 
    45     x, y = im.size 
    46     r = randint 
    47     # draw 100 random colored boxes on the background 
     48    fgcolor = 'black'; bgcolor = 'gray'; textColor='black' 
    4849 
    49     for num in range(50): 
    50         d.rectangle((r(0,x),r(0,y),r(0,x),r(0,y)),fill=r(0xfff000,0xffffff)) 
     50    #select font for captcha text 
     51    ALL_FONTS=('Bd', 'It', 'MoBI', 'Mono', 'Se', 'BI', 'MoBd', 'MoIt', 'SeBd', '') 
     52    rand_font = random.choice(ALL_FONTS) 
     53    font = ImageFont.truetype(FONT_PATH+'/vera/Vera%s.ttf'%rand_font, fnt_sz) 
     54    textSize = font.getsize(text) 
    5155 
    52     # add the text to the image 
    53     d.text((3,3), text, font=font, fill=fgcolor) 
    54      
    55     for num in range(10): 
    56         d.line([(r(0,x), r(0,y)), (r(0,x), r(0,y))], fill=r(0xf0f000, 0xffffff)) 
     56#------------------------------render   background1 ----------------------- 
     57    image = Image.new('RGB', (textSize[0]+10,textSize[1]+10), bgcolor) 
     58    image.paste(bgcolor) 
     59#------------------------------render       Text2 ------------------------ 
     60    draw = ImageDraw.Draw(image) 
     61    alignment = (random.uniform(0,1), random.uniform(0,1)) 
     62    x = int((image.size[0] - textSize[0]) * alignment[0] + 0.5) 
     63    y = int((image.size[1] - textSize[1]) * alignment[1] + 0.5) 
    5764 
    58     im = im.filter(ImageFilter.EDGE_ENHANCE_MORE
     65    draw.text((x,y), text, font=font, fill=textColor
    5966 
     67#------------------------------render       Distortion3 ----------------------- 
     68    r = 1 
     69    xPoints = image.size[0] / r + 2 
     70    yPoints = image.size[1] / r + 2 
     71    f = getTransform(image) 
     72 
     73    # Create a list of arrays with transformed points 
     74    xRows = [] 
     75    yRows = [] 
     76    for j in xrange(yPoints): 
     77        xRow = [] 
     78        yRow = [] 
     79        for i in xrange(xPoints): 
     80            x, y = f(i*r, j*r) 
     81 
     82            # Clamp the edges so we don't get black undefined areas 
     83            x = max(0, min(image.size[0]-1, x)) 
     84            y = max(0, min(image.size[1]-1, y)) 
     85 
     86            xRow.append(x) 
     87            yRow.append(y) 
     88        xRows.append(xRow) 
     89        yRows.append(yRow) 
     90 
     91    # Create the mesh list, with a transformation for 
     92    # each square between points on the grid 
     93    mesh = [] 
     94    for j in xrange(yPoints-1): 
     95        for i in xrange(xPoints-1): 
     96            mesh.append(( 
     97                # Destination rectangle 
     98                (i*r, j*r, 
     99                 (i+1)*r, (j+1)*r), 
     100                # Source quadrilateral 
     101                (xRows[j  ][i  ], yRows[j  ][i  ], 
     102                 xRows[j+1][i  ], yRows[j+1][i  ], 
     103                 xRows[j+1][i+1], yRows[j+1][i+1], 
     104                 xRows[j  ][i+1], yRows[j  ][i+1]), 
     105                )) 
     106 
     107    img = image.transform(image.size, Image.MESH, mesh, Image.BILINEAR) 
     108 
     109#--------------------------------------------------------------------------- 
    60110    # save the image to a file 
    61     im.save(outFile, format=fmt) 
     111    img.save(outFile, format=fmt) 
    62112    outFile.seek(0) 
    63113    src = outFile.read()