Skip to content

Core Utilities

Sepehr0Day edited this page Jun 13, 2026 · 1 revision

Core Utilities

These APIs are useful when creating custom generators. Generator classes and CaptchaConfig are the stable high-level interface; lower-level rendering helpers may evolve between releases.

CaptchaConfig.size

Returns (width, height).

config = CaptchaConfig(width=800, height=480)
assert config.size == (800, 480)

CaptchaConfig.extension

Returns the normalized file extension for output_format.

config = CaptchaConfig(output_format="JPEG")
assert config.extension == "jpg"

random_color

random_color() -> tuple[int, int, int]

Returns a random RGB tuple.

from CaptchaGenerator.core.colors import random_color

fill = random_color()

random_color_name

random_color_name() -> str

Returns a random supported named color.

grid_positions

grid_positions(
    count: int,
    width: int,
    height: int,
    margin: int,
) -> list[tuple[int, int]]

Creates evenly distributed center points.

positions = grid_positions(12, 800, 480, 60)
for x, y in positions:
    draw.ellipse((x - 5, y - 5, x + 5, y + 5), fill="red")

regular_polygon

regular_polygon(
    center: tuple[float, float],
    radius: float,
    sides: int,
    rotation: float = 0,
) -> list[tuple[float, float]]
points = regular_polygon((200, 200), 80, sides=6)
draw.polygon(points, fill="blue")

draw_shape

draw_shape(
    draw,
    shape: str,
    x: int,
    y: int,
    size: int,
    color,
    *,
    outline=(25, 35, 50, 230),
    line_width: int = 3,
) -> None

Supported shapes are exported as CaptchaGenerator.core.SHAPES.

draw_shape(draw, "circle", 100, 100, 30, (45, 105, 190))

fit_image

fit_image(source: Image.Image, size: tuple[int, int]) -> Image.Image

Fits an image inside a white canvas while preserving aspect ratio.

thumbnail = fit_image(Image.open("photo.png"), (320, 200))

validate_text_request

validate_text_request(
    *,
    length: int,
    values: str,
    fonts: Sequence[str],
) -> None

Validates text CAPTCHA input and raises InvalidArgumentError for invalid length, empty values or unusable input.

create_background

create_background(source: Image.Image | None = None) -> Image.Image

Creates the standard renderer canvas or normalizes the supplied source.

background = create_background(Image.open("background.png"))

get_render_settings

get_render_settings(
    difficulty: str,
    style: str,
) -> RenderSettings

Resolves text distortion, noise and rendering settings.

settings = get_render_settings("hard", "wave")

render_captcha

render_captcha(
    text: str,
    *,
    font_loader,
    fonts: list[str],
    background: Image.Image | None = None,
    preferred_colors: Sequence[str] | None = None,
    difficulty: str = "medium",
    style: str = "modern",
) -> Image.Image
generator = TextCaptcha()
image = render_captcha(
    "ABCD42",
    font_loader=generator._load_font,
    fonts=[],
    preferred_colors=["navy", "darkred"],
    difficulty="hard",
    style="wave",
)

Noise Drawing

The following mutate a Pillow ImageDraw object:

draw_circle(draw, width, height)
draw_rectangle(draw, width, height)
draw_square(draw, width, height)
draw_triangle(draw, width, height)
draw_random_shape(draw, width, height)
draw_noise_lines(draw, width, height, count=...)
draw_noise_shapes(draw, width, height, count=...)
from PIL import Image, ImageDraw
from CaptchaGenerator.core.noise import draw_noise_lines, draw_noise_shapes

image = Image.new("RGB", (720, 240), "white")
draw = ImageDraw.Draw(image)
draw_noise_lines(draw, image.width, image.height, count=8)
draw_noise_shapes(draw, image.width, image.height, count=20)

wrap_text

wrap_text(draw, text, font, maximum_width) -> list[str]

Splits a question into renderable lines.

lines = wrap_text(draw, long_question, font, maximum_width=600)

Maze Utilities

carve_maze

carve_maze(columns: int, rows: int) -> dict[Cell, set[Cell]]

Creates a randomized connected maze graph.

solve_maze

solve_maze(
    graph: dict[Cell, set[Cell]],
    start: Cell,
    end: Cell,
) -> list[Cell]

Returns the path from start to end.

path_to_directions

path_to_directions(path: list[Cell]) -> list[str]

Converts a cell path to up, down, left, and right.

graph = carve_maze(10, 7)
path = solve_maze(graph, (0, 0), (9, 6))
moves = path_to_directions(path)

Puzzle Helpers

procedural_puzzle_background

procedural_puzzle_background(config: CaptchaConfig) -> Image.Image

Creates a detailed generated background for irregular puzzles.

math_grid

math_grid(count: int) -> int

Returns a suitable square-grid dimension.

create_arrow_icon

create_arrow_icon(size: int, fill: Color, outline: Color) -> Image.Image
icon = create_arrow_icon(96, "#3b82f6", "#172033")

math_cos and math_sin

Thin wrappers used by irregular puzzle geometry:

x = math_cos(angle)
y = math_sin(angle)

Clone this wiki locally