hbutils.color.utils

Color utility helpers for perceptual distance, random palettes, and gradients.

This module provides utility functions built on top of hbutils.color.model.Color for common color-related operations:

The functions are designed to accept Color objects, CSS3 color names, hexadecimal strings, or RGB tuples when appropriate.

Example:

>>> from hbutils.color import visual_distance, rnd_colors, linear_gradient
>>>
>>> visual_distance('red', '#00ff00')
2.5495097567963922
>>>
>>> for c in rnd_colors(3):
...     print(c)
#ff00ee
#00ff00
#009cff
>>>
>>> grad = linear_gradient(('red', 'yellow', 'lime'))
>>> grad(0.5)
<Color yellow>

__all__

hbutils.color.utils.__all__ = ['visual_distance', 'rnd_colors', 'linear_gradient']

Built-in mutable sequence.

If no argument is given, the constructor creates a new empty list. The argument must be an iterable if specified.

visual_distance

hbutils.color.utils.visual_distance(c1: Color | str, c2: Color | str) float[source]

Calculate the visual distance between two colors.

This function computes the perceptual distance between two colors using a weighted Euclidean distance in RGB space. The weights are based on the average red component to account for human perception differences.

Parameters:
  • c1 (Union[Color, str]) – First color, can be a Color object or string representation.

  • c2 (Union[Color, str]) – Second color, can be a Color object or string representation.

Returns:

Distance value representing visual difference between colors.

Return type:

float

Raises:
  • TypeError – If either color is an unsupported type.

  • ValueError – If a string color is invalid.

Examples:

>>> from hbutils.color import visual_distance
>>> visual_distance('#ff0000', '#00ff00')
2.5495097567963922
>>> visual_distance('#778800', '#887700')
0.16996731711975946

rnd_colors

hbutils.color.utils.rnd_colors(count: int, lightness: float = 0.5, saturation: float = 1.0, alpha: float | None = None, init_dis: float = 4.0, lr: float = 0.95, ur: float = 1.5, rnd: Random | None = None) Iterator[Color][source]

Generate random colors that are visually distinct from each other.

This generator creates count colors in HLS space and enforces a minimum visual distance between each new color and all previously generated colors. When many attempts fail, the minimum distance is relaxed; when generation succeeds quickly, the distance is increased.

Parameters:
  • count (int) – Number of colors to generate.

  • lightness (float) – Lightness value in HLS color space (0.0 to 1.0).

  • saturation (float) – Saturation value in HLS color space (0.0 to 1.0).

  • alpha (Optional[float]) – Alpha (transparency) value for colors; None means no alpha.

  • init_dis (float) – Initial minimum distance between colors.

  • lr (float) – Lower ratio for decreasing minimum distance after failures.

  • ur (float) – Upper ratio for increasing minimum distance after successes.

  • rnd (Optional[random.Random]) – Random number generator instance; if None, random.Random(0) is used.

Returns:

Iterator yielding Color objects.

Return type:

Iterator[Color]

Note

The generator yields colors lazily; iteration triggers the generation.

Examples:

>>> from hbutils.color import rnd_colors
>>> for c in rnd_colors(3):
...     print(c)
#ff00ee
#00ff00
#009cff

>>> for c in rnd_colors(3, 0.8, 0.9):
...     print(c)
#fa9ef4
#9efaa1
#9eb4fa

linear_gradient

hbutils.color.utils.linear_gradient(colors: Sequence[Color | str | Tuple[float, float, float]] | Sequence[Tuple[float, Color | str | Tuple[float, float, float]]]) Callable[[float], Color][source]

Create a linear gradient function from a sequence of colors.

This function creates a gradient mapping that interpolates linearly between the provided colors. Colors can be provided either as a simple sequence (evenly distributed) or as position-color tuples for custom positioning.

Parameters:

colors (Union[Sequence[Union[Color, str, Tuple[float, float, float]]], Sequence[Tuple[float, Union[Color, str, Tuple[float, float, float]]]]]) – Sequence of colors or position-color tuples. If a simple sequence, colors are evenly distributed from 0 to 1. If tuples, the first element is position and the second is the color.

Returns:

A function that maps a float position to the interpolated color.

Return type:

Callable[[float], Color]

Raises:
  • AssertionError – If control points are empty or not strictly increasing.

  • ZeroDivisionError – If only one control point is provided.

  • TypeError – If input is not iterable or contains invalid elements.

  • ValueError – If the gradient function is evaluated outside valid range or if any color value is invalid.

Examples:

- Simple Linear Gradientation

>>> from hbutils.color import linear_gradient
>>>
>>> f = linear_gradient(('red', 'yellow', 'lime'))
>>> f(0)
<Color red>
>>> f(0.25)
<Color #ff8000>
>>> f(0.5)
<Color yellow>
>>> f(1)
<Color lime>

- Complex Linear Gradientation

>>> f = linear_gradient(((-0.2, 'red'), (0.7, '#ffff0044'), (1.1, 'lime')))
>>> f(-0.2)
<Color red, alpha: 1.000>
>>> f(0.7)
<Color yellow, alpha: 0.267>
>>> f(1.1)
<Color lime, alpha: 1.000>