Difference between revisions of "Captcha"

From Publication Station
Line 38: Line 38:
img_ext = 'png' # image extension. Supported formats: eps, jpeg, jpg, pdf, pgf, png, ps, raw, rgba, svg, svgz, tif, tiff.
img_ext = 'png' # image extension. Supported formats: eps, jpeg, jpg, pdf, pgf, png, ps, raw, rgba, svg, svgz, tif, tiff.


def makeImage(text, width=400, height=200, angle=None, ext='png', rgbcolor=(1,0,1)):                                                                                        
def makeImage(text, width=400, height=200, angle=None, ext='png', rgbcolor=(1,0,1)):
     '''Generate a 3d CAPTCHA image.                                                                                                                                          
     '''Generate a 3d CAPTCHA image.
     Args:                                                                                                                                                                    
     Args:
         text: Text in the image.                                                                                                                                            
         text: Text in the image.
         width: Image width in pixel.                                                                                                                                        
         width: Image width in pixel.
         height: Image height in pixel.                                                                                                                                      
         height: Image height in pixel.
         angle: The angle between text and X axis.                                                                                                                            
         angle: The angle between text and X axis.
     Returns:                                                                                                                                                                
     Returns:
         Binary data of CAPTCHA image in PNG format.                                                                                                                          
         Binary data of CAPTCHA image in PNG format.
     '''                                                                                                                                                                      
     '''
     angle = angle if angle != None else uniform(-20, 20)                                                                                                                    
     angle = angle if angle != None else uniform(-20, 20)
     try:                                                                                                                                                                    
     try:
         font = ImageFont.truetype(fontPath, 24)                                                                                                                              
         font = ImageFont.truetype(fontPath, 24)
     except IOError:                                                                                                                                                          
     except IOError:
         raise IOError(                                                                                                                                                      
         raise IOError(
             'Font file doesn\'t exist. Please set `fontPath` correctly.')                                                                                                    
             'Font file doesn\'t exist. Please set `fontPath` correctly.')
     txtW, txtH = font.getsize(text)                                                                                                                                          
     txtW, txtH = font.getsize(text)
     img = Image.new('L', (txtW * 3, txtH * 3), color=255)                                                                                                                    
     img = Image.new('L', (txtW * 3, txtH * 3), color=255)
     drw = ImageDraw.Draw(img)                                                                                                                                                
     drw = ImageDraw.Draw(img)
     drw.text((txtW, txtH), text, font=font)                                                                                                                                  
     drw.text((txtW, txtH), text, font=font)
                                                                                                                                                                             
   
     fig = pylab.figure(figsize=(width/100.0, height/100.0))                                                                                                                  
     fig = pylab.figure(figsize=(width/100.0, height/100.0))
     ax = Axes3D(fig)                                                                                                                                                        
     ax = Axes3D(fig)
     X, Y = numpy.meshgrid(range(img.size[0]), range(img.size[1]))                                                                                                            
     X, Y = numpy.meshgrid(range(img.size[0]), range(img.size[1]))
     Z = 1 - numpy.asarray(img) / 255                                                                                                                                        
     Z = 1 - numpy.asarray(img) / 255
     ax.plot_wireframe(X, -Y, Z, rstride=1, cstride=1, color=( rgbcolor ) ) # "plot_wireframe" can be replace by "plot_surface" to produce a surface                          
     ax.plot_wireframe(X, -Y, Z, rstride=1, cstride=1, color=( rgbcolor ) ) # "plot_wireframe" can be replace by "plot_surface" to produce a surface
     ax.set_zlim((-3, 3))                                                                                                                                                    
     ax.set_zlim((-3, 3))
     ax.set_xlim((txtW * 1.1, txtW * 1.9))                                                                                                                                    
     ax.set_xlim((txtW * 1.1, txtW * 1.9))
     ax.set_ylim((-txtH * 1.9, -txtH * 1.1))                                                                                                                                  
     ax.set_ylim((-txtH * 1.9, -txtH * 1.1))
     ax.set_axis_off()                                                                                                                                                        
     ax.set_axis_off()
     ax.view_init(elev=60, azim=-90 + angle)        
     ax.view_init(elev=60, azim=-90 + angle)
 
     fim = StringIO()
     fim = StringIO()
     fig.savefig(fim, format=ext)
     fig.savefig(fim, format=ext)
Line 78: Line 79:
     degrees = [i*10 for i in range(0,36)] # list different degrees
     degrees = [i*10 for i in range(0,36)] # list different degrees
     for n in degrees: # for loop will produce 35 different images, each in a different angle         
     for n in degrees: # for loop will produce 35 different images, each in a different angle         
         img = makeImage(text='Are you human?', width=600, height=300, angle=n, ext=img_ext ) # Essential command: text, width, height, angle   
         img = makeImage(text='Are you human?', width=600, height=300, angle=n, ext=img_ext, rgbcolor=(0.05,0.8,0.3) ) # Essential command: text, width, height, angle, extension, color  
         n = str(n).rjust(3, '0')         
         n = str(n).rjust(3, '0')         
         filename = 'human_{}.{}'.format(n, img_ext)
         filename = 'human_{}.{}'.format(n, img_ext)
Line 87: Line 88:
</source>
</source>


Example output:
Example output: with makeImage set to:
img = makeImage(text='Are you human?', width=600, height=300, angle=n, ext=img_ext )
 
[[File:human_010.svg]]
[[File:human_010.svg]]


If line instructing program to plot a wireframe,
ax.plot_wireframe(X, -Y, Z, rstride=1, cstride=1, color=( rgbcolor ) )
is replace for an instruction to plot a surface:
ax.plot_surface(X, -Y, Z, rstride=1, cstride=1, color=( rgbcolor ) )
the result looks like [[File:human_010.png]]


[[Category:cookbook]]
[[Category:cookbook]]

Revision as of 16:03, 10 June 2015

How to generate captchas

The easies way for generating captchas is through libraries in different programming languages (Python, Javascript, PHP, etc) dedicated to this task

Bellow is a list of different libraries used to produce different kind of captchas, dependencies, instructions of how to use them.

Python

3D Captcha

https://github.com/013231/3D-CAPTCHA

  • requires:

Run in the terminal:

python captcha.py

possible changes to script

captcha.py allows different parameters to be changed, namely

  • font-face: fontPath = '/Library/Fonts/Arial.ttf'
  • text used in captch
  • image dimension and format
  • image color
  • image 3D position

Here is a modified, simplified, and commented version of the captcha.py script:

 
#!/usr/bin/env python 
# encoding=utf-8

from random import uniform, shuffle
from cStringIO import StringIO
from PIL import ImageFont, Image, ImageDraw
import numpy, pylab
from mpl_toolkits.mplot3d import Axes3D

fontPath = '/Library/Fonts/Arial.ttf' # path to font used
img_ext = 'png' # image extension. Supported formats: eps, jpeg, jpg, pdf, pgf, png, ps, raw, rgba, svg, svgz, tif, tiff.

def makeImage(text, width=400, height=200, angle=None, ext='png', rgbcolor=(1,0,1)):
    '''Generate a 3d CAPTCHA image.
    Args:
        text: Text in the image.
        width: Image width in pixel.
        height: Image height in pixel.
        angle: The angle between text and X axis.
    Returns:
        Binary data of CAPTCHA image in PNG format.
    '''
    angle = angle if angle != None else uniform(-20, 20)
    try:
        font = ImageFont.truetype(fontPath, 24)
    except IOError:
        raise IOError(
            'Font file doesn\'t exist. Please set `fontPath` correctly.')
    txtW, txtH = font.getsize(text)
    img = Image.new('L', (txtW * 3, txtH * 3), color=255)
    drw = ImageDraw.Draw(img)
    drw.text((txtW, txtH), text, font=font)
    
    fig = pylab.figure(figsize=(width/100.0, height/100.0))
    ax = Axes3D(fig)
    X, Y = numpy.meshgrid(range(img.size[0]), range(img.size[1]))
    Z = 1 - numpy.asarray(img) / 255
    ax.plot_wireframe(X, -Y, Z, rstride=1, cstride=1, color=( rgbcolor ) ) # "plot_wireframe" can be replace by "plot_surface" to produce a surface
    ax.set_zlim((-3, 3))
    ax.set_xlim((txtW * 1.1, txtW * 1.9))
    ax.set_ylim((-txtH * 1.9, -txtH * 1.1))
    ax.set_axis_off()
    ax.view_init(elev=60, azim=-90 + angle)

    fim = StringIO()
    fig.savefig(fim, format=ext)
    binData = fim.getvalue()
    fim.close()
    return binData

if __name__ == '__main__':
    degrees = [i*10 for i in range(0,36)] # list different degrees
    for n in degrees: # for loop will produce 35 different images, each in a different angle         
        img = makeImage(text='Are you human?', width=600, height=300, angle=n, ext=img_ext, rgbcolor=(0.05,0.8,0.3) ) # Essential command: text, width, height, angle, extension, color  
        n = str(n).rjust(3, '0')        
        filename = 'human_{}.{}'.format(n, img_ext)
        print filename
        with open(filename, 'wb') as f:
            f.write(img)

Example output: with makeImage set to:

img = makeImage(text='Are you human?', width=600, height=300, angle=n, ext=img_ext )

Human 010.svg

If line instructing program to plot a wireframe,

ax.plot_wireframe(X, -Y, Z, rstride=1, cstride=1, color=( rgbcolor ) ) 

is replace for an instruction to plot a surface:

ax.plot_surface(X, -Y, Z, rstride=1, cstride=1, color=( rgbcolor ) ) 

the result looks like File:Human 010.png