Criando um Gerador de Captcha Visual com Python e Pillow

Para desenvolver um sistema de captcha visual em Python, a biblioteca Pillow é a ferramenta ideal. O primeiro passo é instalar o pacote através do gerenciador de pacotes:

pip install Pillow

Fundamentos de Manipulação de Imagens

A criação de uma imagem base é feita utilizando a classe Image. Abaixo, demonstramos como inicializar uma tela em branco e salvar o resultado em disco.

from PIL import Image

# Inicializa uma tela de 500x500 pixels com fundo branco
canvas = Image.new(mode="RGB", size=(500, 500), color=(255, 255, 255))

# Persiste a imagem no sistema de arquivos
canvas.save("tela_base.png", format="PNG")

Para desenhar formas e textos, utilizamos o objeto ImageDraw, que atua como um pincel sobre a imagem.

from PIL import ImageDraw

# Cria o objeto de desenho vinculado ao canvas
pincel = ImageDraw.Draw(canvas, mode="RGB")

# Desenha pontos em coordenadas específicas
pincel.point((150, 150), fill="red")
pincel.point((200, 200), fill=(0, 0, 0))

# Traça linhas retas
pincel.line((100, 50, 100, 250), fill="blue", width=2)
pincel.line((50, 100, 250, 100), fill="green", width=2)

# Desenha arcos e circunferências
pincel.arc((100, 300, 300, 500), start=0, end=360, fill="purple")
pincel.arc((200, 200, 400, 400), start=45, end=135, fill="orange")

Adicionando Tipografia Personalizada

A renderização de texto simples pode ser feita diretamente, mas para captchas, é comum utilizar fontes personalizadas para dificultar a leitura por bots.

from PIL import ImageFont

# Carrega uma fonte TrueType com tamanho específico
fonte_custom = ImageFont.truetype("arial.ttf", 32)

# Renderiza texto padrão
pincel.text((10, 10), "Texto Simples", fill="black")

# Renderiza texto com a fonte customizada
pincel.text((10, 50), "Texto Customizado", fill="darkblue", font=fonte_custom)

Implementação do Gerader de Captcha

Combinando os conceitos acima, podemos estruturar um gerador de captcha que produz uma imagem com caracteres aleatórios, cores variadas e um fundo dinâmico.

import random
from PIL import Image, ImageDraw, ImageFont

def gerar_captcha_visual(largura=160, altura=60, qtd_caracteres=4):
    # Gera um fundo com cor aleatória suave
    cor_fundo = (random.randint(200, 255), random.randint(200, 255), random.randint(200, 255))
    imagem = Image.new("RGB", (largura, altura), cor_fundo)
    desenho = ImageDraw.Draw(imagem)
    
    # Tenta carregar uma fonte, fallback para a padrão se falhar
    try:
        tipo_fonte = ImageFont.truetype("arial.ttf", 40)
    except IOError:
        tipo_fonte = ImageFont.load_default()
        
    codigo = ""
    
    for indice in range(qtd_caracteres):
        # Sorteia entre letras maiúsculas e números
        caractere = random.choice("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
        codigo += caractere
        
        # Cor aleatória e contrastante para o caractere
        cor_texto = (random.randint(0, 150), random.randint(0, 150), random.randint(0, 150))
        
        # Calcula a posição X para distribuir os caracteres uniformemente
        pos_x = (largura // (qtd_caracteres + 1)) * (indice + 1) - 10
        pos_y = random.randint(0, altura - 40)
        
        desenho.text((pos_x, pos_y), caractere, font=tipo_fonte, fill=cor_texto)
        
    # Adiciona linhas de ruído para dificultar o OCR
    for _ in range(5):
        x1, y1 = random.randint(0, largura), random.randint(0, altura)
        x2, y2 = random.randint(0, largura), random.randint(0, altura)
        cor_linha = (random.randint(0, 200), random.randint(0, 200), random.randint(0, 200))
        desenho.line((x1, y1, x2, y2), fill=cor_linha, width=2)

    imagem.save("captcha_gerado.png", "PNG")
    return codigo

# Executa a funcao e imprime o codigo gerado para validacao
texto_captcha = gerar_captcha_visual()
print(f"Captcha gerado com sucesso: {texto_captcha}")

Tags: Python Pillow ImageDraw CAPTCHA ImageFont

Publicado em 7-21 09:05