diff --git a/colorhash/__main__.py b/colorhash/__main__.py index 56dee97..2dac7fe 100644 --- a/colorhash/__main__.py +++ b/colorhash/__main__.py @@ -170,7 +170,7 @@ def main() -> None: # Choose the palette palette: list[str] if args.palette == "auto": - palette = matricizer.choose_palette(hashdata, PALETTES) + palette = matricizer.choose_palette(hashdata) else: palette = PALETTES[args.palette] diff --git a/colorhash/matricizer.py b/colorhash/matricizer.py index 111e758..4e41aa5 100644 --- a/colorhash/matricizer.py +++ b/colorhash/matricizer.py @@ -2,7 +2,7 @@ import abc from typing import Mapping, Sequence -from .palettes import Palette, DEFAULT_PALETTES +from .palettes import Palette, DEFAULT_PALETTES, GRADIENT_PALETTES, MULTICOLOR_PALETTES Matrix = Sequence[Sequence[int]] @@ -35,11 +35,18 @@ class Matricizer(metaclass=abc.ABCMeta): :returns: the matrix converted from the hash data. """ - @abc.abstractmethod - def choose_palette(self, data: bytes, palettes: Mapping[str, Palette]) -> Palette: + def choose_palette( + self, data: bytes, palettes: Mapping[str, Palette] | None = None + ) -> Palette: """ Choose a palette based on the give data and palettes. + + By default, this method will choose the Nth palette from the sum of the data mod the length + of all palettes provided (using all palettes as the default). """ + if palettes is None: + palettes = DEFAULT_PALETTES + return list(palettes.values())[sum(data) % len(palettes)] class NibbleMatricizer(Matricizer): @@ -89,8 +96,10 @@ class NibbleMatricizer(Matricizer): return cols - def choose_palette(self, data: bytes, palettes: Mapping[str, Palette]) -> Palette: - return list(palettes.values())[sum(data) % len(palettes)] + def choose_palette( + self, data: bytes, palettes: Mapping[str, Palette] | None = None + ) -> Palette: + return super().choose_palette(data, palettes or GRADIENT_PALETTES) class RandomartMatricizer(Matricizer): @@ -139,5 +148,7 @@ class RandomartMatricizer(Matricizer): rows[r][c] += 1 return rows - def choose_palette(self, _data: bytes, _palettes: Mapping[str, Palette]) -> Palette: - return DEFAULT_PALETTES['rainbow'] + def choose_palette( + self, data: bytes, palettes: Mapping[str, Palette] | None = None + ) -> Palette: + return super().choose_palette(data, palettes or MULTICOLOR_PALETTES) diff --git a/colorhash/palettes.py b/colorhash/palettes.py index 5fc6f7b..7a55403 100644 --- a/colorhash/palettes.py +++ b/colorhash/palettes.py @@ -87,7 +87,7 @@ def hsl_colors(hue: HSVRange, sat: HSVRange, light: HSVRange) -> list[str]: return [f"hsl({h:.02f},{s:.02f}%,{l:.02f}%)" for h, s, l in zip(hue, sat, light)] -DEFAULT_PALETTES = { +GRADIENT_PALETTES = { # Interesting thing with human perception. # Between red and yellow, we can perceive "orange". We have a name for it and see it as a # distinct color. However, between yellow and green, we see a sickly green; between green and @@ -143,9 +143,16 @@ DEFAULT_PALETTES = { "gray-light": StaticPalette(hsl_colors(0, 0, range(50, 100))), "gray-dark": StaticPalette(hsl_colors(0, 0, range(0, 50))), +} + +MULTICOLOR_PALETTES = { "rainbow": StaticPalette(hsl_colors(range(0, 360), 100, 50)), } +DEFAULT_PALETTES = { + **GRADIENT_PALETTES, **MULTICOLOR_PALETTES, +} + PALETTES = {**DEFAULT_PALETTES}