Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to Individually Rotate Letters within a PIL Image?

I am working on a project that involves generating captcha images using Python’s Pillow (PIL) library. I want to add a feature where each individual letter in the captcha string is rotated on the image to make it a more difficult captcha.

import random
from PIL import Image, ImageDraw, ImageFont

def generate_random_string(length):
    random_string = ""
    for i in range(length):
        random_string += random.choice('1234567890ABCDEFGHIJKLMNOPQRSTUVQXYZ')
    return random_string

def generate_captcha():
    fonts = ["Aaargh.ttf", "SerpentineBoldItalic.ttf", "FUTURAM.ttf"]
    randomFont = random.choice(fonts)
    character_count = random.randrange(6, 10)
    captcha_string = generate_random_string(character_count)
    
    captcha_image = Image.new("RGBA", (400, 200), (default_color_red, default_color_green, default_color_blue))
    draw = ImageDraw.Draw(captcha_image, "RGBA")
    
    for i in range(1, 20):
        draw_random_ellipse(draw)
    
    # Arbitrary starting co-ordinates for the text we will write
    x = 10 + random.randrange(0, 100, 1)
    y = 79 + random.randrange(-10, 10, 1)
    
    for letter in captcha_string:
        selected_font = random.choice(fonts)
        font_style = ImageFont.truetype(selected_font, 50)
        
        draw.text((x, y), letter, (0, 0, 0), font=font_style)
       
        x = x + 35
        y = y + random.randrange(-10, 10, 1)
    
    return (captcha_image, captcha_string)

I attempted to find a solution to this problem on my own but couldn’t locate a clear answer. I would greatly appreciate any assistance on how to achieve the goal of rotating each individual letter within a PIL image. Thank you in advance for any help!

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Here’s how you can modify your generate_captcha() function to rotate each letter: create a separate image for each letter, draw the letter on this separate image, rotate the image, paste the rotated image onto the main captcha image.

def generate_captcha():
    fonts = ["Aaargh.ttf", "SerpentineBoldItalic.ttf", "FUTURAM.ttf"]
    character_count = random.randrange(6, 10)
    captcha_string = generate_random_string(character_count)
    
    captcha_image = Image.new("RGBA", (400, 200), (default_color_red, default_color_green, default_color_blue))
    draw = ImageDraw.Draw(captcha_image, "RGBA")
    
    for i in range(1, 20):
        draw_random_ellipse(draw)

    x = 10 + random.randrange(0, 100, 1)
    y = 79 + random.randrange(-10, 10, 1)
    
    for letter in captcha_string:
        selected_font = random.choice(fonts)
        font_style = ImageFont.truetype(selected_font, 50)
        letter_image = Image.new("RGBA", (55, 55), (0, 0, 0, 0)) # Using transparency for empty space
        letter_draw = ImageDraw.Draw(letter_image)
        letter_draw.text((0, 0), letter, (0, 0, 0), font=font_style)
        angle = random.randint(-30, 30)
        rotated_letter = letter_image.rotate(angle, resample=Image.BICUBIC, expand=True)
        paste_pos = (x - rotated_letter.width // 2 + 25, y - rotated_letter.height // 2 + 25)
        captcha_image.paste(rotated_letter, paste_pos, rotated_letter)
        
        x = x + 35
        y = y + random.randrange(-10, 10, 1)
    
    return (captcha_image, captcha_string)
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading