Skip to content

Reference

Here you can find the reference for the user facing API of Pylette. This consists of the extract_colors function, which is used to extract a color palette from an image, and the Palette and Color classes, which are used to work with the extracted color palette.

Pylette.extract_colors

Extracts a set of 'palette_size' colors from the given image.

Parameters:

Name Type Description Default
image ImageType_T

The input image.

required
palette_size int

The number of colors to extract.

5
resize bool

Whether to resize the image before processing.

True
mode Literal['KM'] | Literal['MC']

The color quantization algorithm to use.

'KM'
sort_mode Literal['luminance', 'frequency'] | None

The mode to sort colors.

None

Returns:

Name Type Description
Palette Palette

A palette of the extracted colors.

Examples:

Colors can be extracted from a variety of sources, including local files, byte streams, URLs, and numpy arrays.

>>> extract_colors("path/to/image.jpg", palette_size=5, resize=True, mode="KM", sort_mode="luminance")
>>> extract_colors(b"image_bytes", palette_size=5, resize=True, mode="KM", sort_mode="luminance")
Source code in Pylette/src/color_extraction.py
def extract_colors(
    image: ImageType_T,
    palette_size: int = 5,
    resize: bool = True,
    mode: Literal["KM"] | Literal["MC"] = "KM",
    sort_mode: Literal["luminance", "frequency"] | None = None,
) -> Palette:
    """
    Extracts a set of 'palette_size' colors from the given image.

    Parameters:
        image: The input image.
        palette_size: The number of colors to extract.
        resize: Whether to resize the image before processing.
        mode: The color quantization algorithm to use.
        sort_mode: The mode to sort colors.

    Returns:
        Palette: A palette of the extracted colors.

    Examples:
        Colors can be extracted from a variety of sources, including local files, byte streams, URLs, and numpy arrays.

        >>> extract_colors("path/to/image.jpg", palette_size=5, resize=True, mode="KM", sort_mode="luminance")
        >>> extract_colors(b"image_bytes", palette_size=5, resize=True, mode="KM", sort_mode="luminance")
    """

    image_type = _parse_image_type(image)

    match image_type:
        case ImageType.PATH:
            img = Image.open(image).convert("RGB")
        case ImageType.BYTES:
            assert isinstance(image, bytes)
            img = Image.open(BytesIO(image)).convert("RGB")
        case ImageType.URL:
            assert isinstance(image, str)
            img = request_image(image)
        case ImageType.ARRAY:
            img = Image.fromarray(image).convert("RGB")
        case ImageType.NONE:
            raise ValueError(f"Unable to parse image source. Got image type {type(image)}")

    # open the image
    if resize:
        img = img.resize((256, 256))
    width, height = img.size
    arr = np.asarray(img)

    if mode == "KM":
        colors = k_means_extraction(arr, height, width, palette_size)
    elif mode == "MC":
        colors = median_cut_extraction(arr, height, width, palette_size)
    else:
        raise NotImplementedError("Extraction mode not implemented")

    if sort_mode == "luminance":
        colors.sort(key=lambda c: c.luminance, reverse=False)
    else:
        colors.sort(reverse=True)

    return Palette(colors)

Pylette.Palette

Source code in Pylette/src/palette.py
class Palette:
    def __init__(self, colors: list[Color]):
        """
        Initializes a color palette with a list of Color objects.

        Parameters:
            colors (list[Color]): A list of Color objects.
        """

        self.colors = colors
        self.frequencies = [c.freq for c in colors]
        self.number_of_colors = len(colors)

    def display(
        self,
        w: int = 50,
        h: int = 50,
        save_to_file: bool = False,
        filename: str = "color_palette",
        extension: str = "jpg",
    ) -> None:
        """
        Displays the color palette as an image, with an option for saving the image.

        Parameters:
            w (int): Width of each color component.
            h (int): Height of each color component.
            save_to_file (bool): Whether to save the file or not.
            filename (str): Filename.
            extension (str): File extension.
        """
        img = Image.new("RGB", size=(w * self.number_of_colors, h))
        arr = np.asarray(img).copy()
        for i in range(self.number_of_colors):
            c = self.colors[i]
            arr[:, i * h : (i + 1) * h, :] = c.rgb
        img = Image.fromarray(arr, "RGB")
        img.show()

        if save_to_file:
            img.save(f"{filename}.{extension}")

    def __getitem__(self, item: int) -> Color:
        return self.colors[item]

    def __len__(self) -> int:
        return self.number_of_colors

    def to_csv(
        self,
        filename: str | None = None,
        frequency: bool = True,
        colorspace: Literal["rgb", "hsv", "hls"] = "rgb",
        stdout: bool = True,
    ):
        """
        Dumps the palette to stdout. Saves to file if filename is specified.

        Parameters:
            filename (str | None): File to dump to.
            frequency (bool): Whether to dump the corresponding frequency of each color.
            colorspace (Literal["rgb", "hsv", "hls"]): Color space to use.
            stdout (bool): Whether to dump to stdout.
        """

        if stdout:
            for color in self.colors:
                print(",".join(map(str, color.get_colors(colorspace))))

        if filename is not None:
            with open(filename, "w") as palette_file:
                for color in self.colors:
                    palette_file.write(",".join(map(str, color.get_colors(colorspace))))
                    if frequency:
                        palette_file.write(",{}".format(color.freq))
                    palette_file.write("\n")

    def random_color(self, N, mode="frequency"):
        """
        Returns N random colors from the palette, either using the frequency of each color, or choosing uniformly.

        Parameters:
            N (int): Number of random colors to return.
            mode (str): Mode to use for selection. Can be "frequency" or "uniform".

        Returns:
            list[Color]: List of N random colors from the palette.
        """

        if mode == "frequency":
            pdf = self.frequencies
        elif mode == "uniform":
            pdf = None

        return np.random.choice(self.colors, size=N, p=pdf)

    def __str__(self):
        return "".join(["({}, {}, {}, {}) \n".format(c.rgb[0], c.rgb[1], c.rgb[2], c.freq) for c in self.colors])

__init__

Initializes a color palette with a list of Color objects.

Parameters:

Name Type Description Default
colors list[Color]

A list of Color objects.

required
Source code in Pylette/src/palette.py
def __init__(self, colors: list[Color]):
    """
    Initializes a color palette with a list of Color objects.

    Parameters:
        colors (list[Color]): A list of Color objects.
    """

    self.colors = colors
    self.frequencies = [c.freq for c in colors]
    self.number_of_colors = len(colors)

display

Displays the color palette as an image, with an option for saving the image.

Parameters:

Name Type Description Default
w int

Width of each color component.

50
h int

Height of each color component.

50
save_to_file bool

Whether to save the file or not.

False
filename str

Filename.

'color_palette'
extension str

File extension.

'jpg'
Source code in Pylette/src/palette.py
def display(
    self,
    w: int = 50,
    h: int = 50,
    save_to_file: bool = False,
    filename: str = "color_palette",
    extension: str = "jpg",
) -> None:
    """
    Displays the color palette as an image, with an option for saving the image.

    Parameters:
        w (int): Width of each color component.
        h (int): Height of each color component.
        save_to_file (bool): Whether to save the file or not.
        filename (str): Filename.
        extension (str): File extension.
    """
    img = Image.new("RGB", size=(w * self.number_of_colors, h))
    arr = np.asarray(img).copy()
    for i in range(self.number_of_colors):
        c = self.colors[i]
        arr[:, i * h : (i + 1) * h, :] = c.rgb
    img = Image.fromarray(arr, "RGB")
    img.show()

    if save_to_file:
        img.save(f"{filename}.{extension}")

random_color

Returns N random colors from the palette, either using the frequency of each color, or choosing uniformly.

Parameters:

Name Type Description Default
N int

Number of random colors to return.

required
mode str

Mode to use for selection. Can be "frequency" or "uniform".

'frequency'

Returns:

Type Description

list[Color]: List of N random colors from the palette.

Source code in Pylette/src/palette.py
def random_color(self, N, mode="frequency"):
    """
    Returns N random colors from the palette, either using the frequency of each color, or choosing uniformly.

    Parameters:
        N (int): Number of random colors to return.
        mode (str): Mode to use for selection. Can be "frequency" or "uniform".

    Returns:
        list[Color]: List of N random colors from the palette.
    """

    if mode == "frequency":
        pdf = self.frequencies
    elif mode == "uniform":
        pdf = None

    return np.random.choice(self.colors, size=N, p=pdf)

to_csv

Dumps the palette to stdout. Saves to file if filename is specified.

Parameters:

Name Type Description Default
filename str | None

File to dump to.

None
frequency bool

Whether to dump the corresponding frequency of each color.

True
colorspace Literal['rgb', 'hsv', 'hls']

Color space to use.

'rgb'
stdout bool

Whether to dump to stdout.

True
Source code in Pylette/src/palette.py
def to_csv(
    self,
    filename: str | None = None,
    frequency: bool = True,
    colorspace: Literal["rgb", "hsv", "hls"] = "rgb",
    stdout: bool = True,
):
    """
    Dumps the palette to stdout. Saves to file if filename is specified.

    Parameters:
        filename (str | None): File to dump to.
        frequency (bool): Whether to dump the corresponding frequency of each color.
        colorspace (Literal["rgb", "hsv", "hls"]): Color space to use.
        stdout (bool): Whether to dump to stdout.
    """

    if stdout:
        for color in self.colors:
            print(",".join(map(str, color.get_colors(colorspace))))

    if filename is not None:
        with open(filename, "w") as palette_file:
            for color in self.colors:
                palette_file.write(",".join(map(str, color.get_colors(colorspace))))
                if frequency:
                    palette_file.write(",{}".format(color.freq))
                palette_file.write("\n")

Pylette.Color

Source code in Pylette/src/color.py
class Color(object):
    def __init__(self, rgb: tuple[int, ...], frequency: float):
        """
        Initializes a Color object with RGB values and frequency.

        Parameters:
            rgb (tuple[int, ...]): A tuple of RGB values.
            frequency (float): The frequency of the color.
        """
        assert len(rgb) == 3, "RGB values must be a tuple of length 3"
        self.rgb = cast(tuple[int, int, int], rgb)
        self.freq: float = frequency

    def display(self, w: int = 50, h: int = 50) -> None:
        """
        Displays the color in a window of specified width and height.

        Parameters:
        w (int): Width of the window in pixels.
        h (int): Height of the window in pixels.
        """
        img = Image.new("RGB", size=(w, h), color=self.rgb)
        img.show()

    def __lt__(self, other: "Color") -> bool:
        """
        Compares the frequency of this color with another color.

        Parameters:
            other (Color): The other Color object to compare with.

        Returns:
            bool: True if the frequency of this color is less than the frequency of the other color, False otherwise.
        """
        return self.freq < other.freq

    def get_colors(self, colorspace: Literal["rgb", "hsv", "hls"] = "rgb") -> tuple[int, ...] | tuple[float, ...]:
        """
        Returns the color values in the specified color space.

        Parameters:
            colorspace (Literal["rgb", "hsv", "hls"]): The color space to use.

        Returns:
            tuple[int, ...] | tuple[float, ...]: The color values in the specified color space.
        """
        colors = {"rgb": self.rgb, "hsv": self.hsv, "hls": self.hls}
        return colors[colorspace]

    @property
    def hsv(self) -> tuple[float, float, float]:
        """
        Converts the RGB color to HSV color space.

        Returns:
            tuple[float, float, float]: The color values in HSV color space.
        """
        return colorsys.rgb_to_hsv(r=self.rgb[0] / 255, g=self.rgb[1] / 255, b=self.rgb[2] / 255)

    @property
    def hls(self) -> tuple[float, float, float]:
        """
        Converts the RGB color to HLS color space.

        Returns:
            tuple[float, float, float]: The color values in HLS color space.
        """
        return colorsys.rgb_to_hls(r=self.rgb[0] / 255, g=self.rgb[1] / 255, b=self.rgb[2] / 255)

    @property
    def luminance(self) -> float:
        """
        Calculates the luminance of the color.

        Returns:
        float: The luminance of the color.
        """
        return np.dot(luminance_weights, self.rgb)

hls: tuple[float, float, float] property

Converts the RGB color to HLS color space.

Returns:

Type Description
tuple[float, float, float]

tuple[float, float, float]: The color values in HLS color space.

hsv: tuple[float, float, float] property

Converts the RGB color to HSV color space.

Returns:

Type Description
tuple[float, float, float]

tuple[float, float, float]: The color values in HSV color space.

luminance: float property

Calculates the luminance of the color.

Returns: float: The luminance of the color.

__init__

Initializes a Color object with RGB values and frequency.

Parameters:

Name Type Description Default
rgb tuple[int, ...]

A tuple of RGB values.

required
frequency float

The frequency of the color.

required
Source code in Pylette/src/color.py
def __init__(self, rgb: tuple[int, ...], frequency: float):
    """
    Initializes a Color object with RGB values and frequency.

    Parameters:
        rgb (tuple[int, ...]): A tuple of RGB values.
        frequency (float): The frequency of the color.
    """
    assert len(rgb) == 3, "RGB values must be a tuple of length 3"
    self.rgb = cast(tuple[int, int, int], rgb)
    self.freq: float = frequency

__lt__

Compares the frequency of this color with another color.

Parameters:

Name Type Description Default
other Color

The other Color object to compare with.

required

Returns:

Name Type Description
bool bool

True if the frequency of this color is less than the frequency of the other color, False otherwise.

Source code in Pylette/src/color.py
def __lt__(self, other: "Color") -> bool:
    """
    Compares the frequency of this color with another color.

    Parameters:
        other (Color): The other Color object to compare with.

    Returns:
        bool: True if the frequency of this color is less than the frequency of the other color, False otherwise.
    """
    return self.freq < other.freq

display

Displays the color in a window of specified width and height.

Parameters: w (int): Width of the window in pixels. h (int): Height of the window in pixels.

Source code in Pylette/src/color.py
def display(self, w: int = 50, h: int = 50) -> None:
    """
    Displays the color in a window of specified width and height.

    Parameters:
    w (int): Width of the window in pixels.
    h (int): Height of the window in pixels.
    """
    img = Image.new("RGB", size=(w, h), color=self.rgb)
    img.show()

get_colors

Returns the color values in the specified color space.

Parameters:

Name Type Description Default
colorspace Literal['rgb', 'hsv', 'hls']

The color space to use.

'rgb'

Returns:

Type Description
tuple[int, ...] | tuple[float, ...]

tuple[int, ...] | tuple[float, ...]: The color values in the specified color space.

Source code in Pylette/src/color.py
def get_colors(self, colorspace: Literal["rgb", "hsv", "hls"] = "rgb") -> tuple[int, ...] | tuple[float, ...]:
    """
    Returns the color values in the specified color space.

    Parameters:
        colorspace (Literal["rgb", "hsv", "hls"]): The color space to use.

    Returns:
        tuple[int, ...] | tuple[float, ...]: The color values in the specified color space.
    """
    colors = {"rgb": self.rgb, "hsv": self.hsv, "hls": self.hls}
    return colors[colorspace]

Pylette.ImageType_T: TypeAlias = Union['os.PathLike[Any]', bytes, NDArray[float], str] module-attribute