Generate Captcha using Python

A modified version of the PIL called Pillow library can be used to generate a textbased CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart) in Python.

Types of CAPTCHA

There are different types of CAPTCHA and some of them are as follows ?

  • Textbased CAPTCHA A sequence of characters is provided with features distorted and random noise to make character recognition difficult.

  • Imagebased CAPTCHA Images are provided to humans and features are distorted to make image recognition for computers difficult.

  • Audiobased CAPTCHA An audio recording of spoken characters or clips is provided to humans which they need to input into the system correctly.

  • Behavioural CAPTCHA To make it difficult for the bots to replicate/automate.

Generating a TextBased CAPTCHA

Using the Pillow library we can generate a textbased CAPTCHA, which allows us to create and manipulate images in Python. The steps included are as follows ?

  • Creating a blank image

  • Generating random CAPTCHA text

  • Defining the font, text size and positioning

  • Adding noise for security

  • Saving the CAPTCHA image

Complete CAPTCHA Generator Example

from PIL import Image, ImageDraw, ImageFont
import random
import string

def generate_captcha(width, height, length):
    # Create a blank image with a white background
    image = Image.new('RGB', (width, height), 'white')
    draw = ImageDraw.Draw(image)
    
    # Generate random CAPTCHA text
    captcha_text = ''.join(random.choices(string.ascii_uppercase + string.digits, k=length))
    
    try:
        # Try to load a system font
        font = ImageFont.truetype('arial.ttf', 72)
    except:
        # Fallback to default font if arial.ttf is not available
        font = ImageFont.load_default()
    
    # Calculate text size and center position
    bbox = draw.textbbox((0, 0), captcha_text, font=font)
    t_width = bbox[2] - bbox[0]
    t_height = bbox[3] - bbox[1]
    text_x = (width - t_width) / 2
    text_y = (height - t_height) / 2
    
    # Draw the CAPTCHA text
    draw.text((text_x, text_y), captcha_text, font=font, fill='black')
    
    # Add random noise to make it harder for bots
    for _ in range(1000):
        x = random.randint(0, width - 1)
        y = random.randint(0, height - 1)
        draw.point((x, y), fill='gray')
    
    # Add random lines for extra security
    for _ in range(5):
        x1, y1 = random.randint(0, width), random.randint(0, height)
        x2, y2 = random.randint(0, width), random.randint(0, height)
        draw.line([(x1, y1), (x2, y2)], fill='lightgray', width=2)
    
    return image, captcha_text

# Generate CAPTCHA
width = 300
height = 100
length = 5

captcha_image, captcha_text = generate_captcha(width, height, length)
print(f"Generated CAPTCHA text: {captcha_text}")
captcha_image.save('captcha.png')
print("CAPTCHA image saved as 'captcha.png'")
Generated CAPTCHA text: A7K9M
CAPTCHA image saved as 'captcha.png'

Key Components Explained

Image Creation

The Image.new('RGB', (width, height), 'white') creates a blank white canvas, and ImageDraw.Draw(image) allows us to draw text and shapes on it.

Random Text Generation

The random.choices() function selects random characters from uppercase letters and digits, while join() combines them into a string.

Font Handling

The code uses a tryexcept block to handle font loading gracefully. If the system font is unavailable, it falls back to the default font.

Noise Addition

Random dots and lines are added to make the CAPTCHA more secure against automated recognition systems.

Enhanced CAPTCHA with Colors

from PIL import Image, ImageDraw, ImageFont
import random
import string

def generate_colorful_captcha(width, height, length):
    # Create image with random background color
    bg_color = (random.randint(200, 255), random.randint(200, 255), random.randint(200, 255))
    image = Image.new('RGB', (width, height), bg_color)
    draw = ImageDraw.Draw(image)
    
    # Generate random text
    captcha_text = ''.join(random.choices(string.ascii_uppercase + string.digits, k=length))
    
    try:
        font = ImageFont.truetype('arial.ttf', 60)
    except:
        font = ImageFont.load_default()
    
    # Calculate position
    bbox = draw.textbbox((0, 0), captcha_text, font=font)
    t_width = bbox[2] - bbox[0]
    t_height = bbox[3] - bbox[1]
    text_x = (width - t_width) / 2
    text_y = (height - t_height) / 2
    
    # Draw text with random color
    text_color = (random.randint(0, 100), random.randint(0, 100), random.randint(0, 100))
    draw.text((text_x, text_y), captcha_text, font=font, fill=text_color)
    
    return image, captcha_text

# Generate colorful CAPTCHA
colorful_image, text = generate_colorful_captcha(250, 80, 4)
print(f"Colorful CAPTCHA text: {text}")
colorful_image.save('colorful_captcha.png')
Colorful CAPTCHA text: B3X7

Conclusion

Python's Pillow library makes it easy to generate secure CAPTCHAs with random text, noise, and visual distortions. The key is balancing readability for humans while making it difficult for automated systems to recognize.

Updated on: 2026-03-27T12:00:23+05:30

2K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements