def add_text_to_image(
    image: Image.Image,
    text: str,
    font: str | None = None,
    size: int | None = None,
    color: tuple[int, int, int] | str = "white",
    background: tuple[int, ...] | str | None = (0, 0, 0, 128),  # Default to semi-transparent black
    position: tuple[int, int] = (10, 10),
    padding: int = 3,
) -> Image.Image:
    """Add text to an image with configurable parameters.

    This function adds text to a PIL Image with customizable font, size, color and
    background options. The text can be positioned anywhere on the image and includes
    an optional background box.

    Args:
        image (Image.Image): The PIL Image to add text to.
        text (str): The text string to add to the image.
        font (str | None, optional): Path to a font file. If ``None`` or loading fails,
            the default system font is used. Defaults to ``None``.
        size (int | None, optional): Font size in pixels. If ``None``, size is
            calculated dynamically based on image dimensions. Defaults to ``None``.
        color (tuple[int, int, int] | str, optional): Text color as RGB tuple or color
            name. Defaults to ``"white"``.
        background (tuple[int, ...] | str | None, optional): Background color for text
            box. Can be RGB/RGBA tuple or color name. If ``None``, no background is
            drawn. Defaults to semi-transparent black ``(0, 0, 0, 128)``.
        position (tuple[int, int], optional): Top-left position of text as ``(x, y)``
            coordinates. Defaults to ``(10, 10)``.
        padding (int, optional): Padding around text in background box in pixels.
            Defaults to ``3``.

    Returns:
        Image.Image: New PIL Image with text added.

    Examples:
        Basic white text:

        >>> from PIL import Image
        >>> img = Image.new('RGB', (200, 100))
        >>> result = add_text_to_image(img, "Hello")

        Custom font and color:

        >>> result = add_text_to_image(
        ...     img,
        ...     "Hello",
        ...     font="arial.ttf",
        ...     color=(255, 0, 0)
        ... )

        Text with custom background:

        >>> result = add_text_to_image(
        ...     img,
        ...     "Hello",
        ...     background=(0, 0, 255, 200),
        ...     position=(50, 50)
        ... )

    Note:
        - The function creates a transparent overlay for the text
        - Font size is calculated dynamically if not specified
        - Falls back to default system font if custom font fails to load
        - Input image is converted to RGBA for compositing
        - Output is converted back to RGB
    """
    # Create a new RGBA image as a transparent overlay
    overlay = Image.new("RGBA", image.size, (0, 0, 0, 0))
    draw = ImageDraw.Draw(overlay)

    if size is None:
        size = dynamic_font_size(image.size)

    try:
        image_font = ImageFont.truetype(font, size) if font else ImageFont.load_default()
    except OSError:
        logger.warning(f"Failed to load font '{font}'. Using default font.")
        image_font = ImageFont.load_default()

    # Calculate text size and position
    text_bbox = draw.textbbox(position, text, font=image_font)
    text_position = position
    background_bbox = (text_bbox[0] - padding, text_bbox[1] - padding, text_bbox[2] + padding, text_bbox[3] + padding)

    # Draw background if specified
    if background is not None:
        draw.rectangle(background_bbox, fill=background)

    # Draw text
    draw.text(text_position, text, font=image_font, fill=color)

    # Composite the overlay onto the original image
    return Image.alpha_composite(image.convert("RGBA"), overlay).convert("RGB")
Add text to an image with configurable parameters.

    This function adds text to a PIL Image with customizable font, size, color and
    background options. The text can be positioned anywhere on the image and includes
    an optional background box.

    Args:
        image (Image.Image): The PIL Image to add text to.
        text (str): The text string to add to the image.
        font (str | None, optional): Path to a font file. If ``None`` or loading fails,
            the default system font is used. Defaults to ``None``.
        size (int | None, optional): Font size in pixels. If ``None``, size is
            calculated dynamically based on image dimensions. Defaults to ``None``.
        color (tuple[int, int, int] | str, optional): Text color as RGB tuple or color
            name. Defaults to ``"white"``.
        background (tuple[int, ...] | str | None, optional): Background color for text
            box. Can be RGB/RGBA tuple or color name. If ``None``, no background is
            drawn. Defaults to semi-transparent black ``(0, 0, 0, 128)``.
        position (tuple[int, int], optional): Top-left position of text as ``(x, y)``
            coordinates. Defaults to ``(10, 10)``.
        padding (int, optional): Padding around text in background box in pixels.
            Defaults to ``3``.

    Returns:
        Image.Image: New PIL Image with text added.

    Examples:
        Basic white text:

        >>> from PIL import Image
        >>> img = Image.new('RGB', (200, 100))
        >>> result = add_text_to_image(img, "Hello")

        Custom font and color:

        >>> result = add_text_to_image(
        ...     img,
        ...     "Hello",
        ...     font="arial.ttf",
        ...     color=(255, 0, 0)
        ... )

        Text with custom background:

        >>> result = add_text_to_image(
        ...     img,
        ...     "Hello",
        ...     background=(0, 0, 255, 200),
        ...     position=(50, 50)
        ... )

    Note:
        - The function creates a transparent overlay for the text
        - Font size is calculated dynamically if not specified
        - Falls back to default system font if custom font fails to load
        - Input image is converted to RGBA for compositing
        - Output is converted back to RGB
    
src/anomalib/visualization/image/functional.py