Home > Blog > Python example - Are you Human?

Python example - Are you Human?

Posted by T800 on December 13, 2010

An example of using the Python Imaging Library or PIL to produce Captcha style pictures from a given text.

It is a contrived acronym for "Completely Automated Public Turing test to tell Computers and Humans Apart".

This snippet of code has been left in its simplistic state as so you can follow the PIL side of the process. For reference you may like to check out the PIL site to follow this article.  This code could easily rewritten as class to Incorporated into other programs were anti-spam or human verification is needed.

human.jpg

There is a download link at the bottom of the page if you with play with this example.

 

  1. #! /usr/bin/env python
  2. #
  3. # Human.py is a Captcha type generator for Linux / Win32 systems with PIL
  4. # Version 1.0.1 - 30 March 2010 - T800
  5.  
  6. import sys
  7. import Image
  8. import ImageFile
  9. import random
  10. import ImageFilter
  11. import ImageChops
  12. import ImageFont
  13. import ImageDraw
  14.  
  15. # User definable variables
  16. #
  17. random_fonts = True # True or False
  18. random_rotate = True # True or False
  19. random_fonts_colour = True # True or False
  20. sizer = 48 # Set font size
  21. text = 'Google' # Test test to created in a CAPTCHA style
  22.  
  23.  
  24. def chr_bitmap( txts, sze, typn, ang):
  25. textlen = len(text)
  26. if random_fonts == True: # Selects a randon font to use
  27. typn = random.randint(0, len(fonts)-1)
  28. else:
  29. typn = 0
  30. if random_rotate == True: # Choose a random slant on chr
  31. ang = random.choice([-25, 0, 25, 45, 0])
  32. else:
  33. ang = 0
  34.  
  35. # Please note that the colours will be inverted as the merge is image.subtract
  36. #
  37. if random_fonts_colour == True:
  38. fcol = random.choice( ['#ff0000', '#00ff00', '#0000ff', '#00ffff', '#ff00ff', '#ffff00', '#7f7f7f'])
  39. else:
  40. fcol = '#ffffff'
  41. font = ImageFont.truetype( fonts[typn], sze )
  42.  
  43. # Returns the width and height of the given text, as a 2-tuple.
  44. #
  45. sizer = font.getsize(txts)
  46.  
  47. im = Image.new('RGBA', sizer, (0, 0, 0, 0)) # Create a blank image with the given size
  48. draw = ImageDraw.Draw(im)
  49. draw.text((0, 0), txts, font=font, fill = fcol ) #Draw text
  50. im = im.rotate(ang, expand=True)
  51. return im, im.size
  52.  
  53. def make_phrase():
  54. maxy = 0 # Default x, y to assemble chr on canvas
  55. maxx = 0
  56. textlen = len(text)
  57. img = []
  58. for txt in range(textlen):
  59. typen = 0
  60. angle = 0
  61. im, (dimx, dimy) = chr_bitmap( text[txt], sizer, typen, angle)
  62. img.append(im)
  63. if dimy > maxy:
  64. maxy=dimy
  65. maxx = maxx + dimx
  66.  
  67. spacer = 0
  68. imgf = Image.open("zat.jpg").convert("RGBA") # Background image
  69. sz2 = ( maxx, maxy+2*spacer)
  70. imgc = imgf.resize( sz2 )
  71. posx = 0
  72. posy = 0
  73.  
  74. for tile in range(len(text)):
  75. (tx, ty) = img[tile].size # get dimentions of chr
  76. rect = (0, 0, tx, ty) # calc rectangle to cut
  77. clip = img[tile].crop(rect) # Cut chr
  78. sz = ( posx, posy, posx + tx, posy + ty) # calc canvas paste
  79. imc = imgc.crop(sz) # cut chr sized lump out of canvas
  80. imd = ImageChops.subtract( imc, clip ) # Merge clip and chr by subtraction
  81. imgc.paste(imd, sz) # Paste it
  82. posx = posx + tx +1
  83. return imgc
  84.  
  85. if __name__=='__main__':
  86.  
  87. br, bg, bb = 255, 255, 255 # Canvas colour
  88.  
  89. fonts = ['fonts/1942.ttf', 'fonts/01 DigiGraphics.ttf', 'fonts/AARDC___.TTF',
  90. 'fonts/abaddon.TTF', 'fonts/Acens.ttf', 'fonts/advent_bold.ttf', 'fonts/BOGSTAND.TTF' ]
  91.  
  92. imgc = make_phrase() # Main Call
  93.  
  94. imgc.save("human.jpg", "JPEG")

Downloads

human.zip 168.87 kB 13-12-2010 21:57 human.zip

Comments:

Leave a Reply



(Your email will not be publicly displayed.)

Please type the letters and numbers shown in the image.Captcha Code