diff --git a/images/release/1.5.1/palette-bare.png b/images/release/1.5.1/palette-bare.png index 6e046df..e64e2c3 100644 Binary files a/images/release/1.5.1/palette-bare.png and b/images/release/1.5.1/palette-bare.png differ diff --git a/images/release/1.5.1/palette.png b/images/release/1.5.1/palette.png index 9a79c13..f663107 100644 Binary files a/images/release/1.5.1/palette.png and b/images/release/1.5.1/palette.png differ diff --git a/monobiome/palette.py b/monobiome/palette.py index af34e66..2011f27 100644 --- a/monobiome/palette.py +++ b/monobiome/palette.py @@ -5,6 +5,10 @@ from importlib.metadata import version from coloraide import Color +from monobiome.util import ( + hex_from_rgb8, + srgb8_from_color, +) from monobiome.constants import ( h_map, L_points, @@ -24,8 +28,8 @@ def compute_hlc_map(notation: str) -> dict[str, Any]: oklch = Color('oklch', [_l/100, _c, _h]) if notation == "hex": - srgb = oklch.convert('srgb') - c_str = srgb.to_string(hex=True) + rgb8 = srgb8_from_color(oklch) + c_str = hex_from_rgb8(rgb8) elif notation == "oklch": ol, oc, oh = oklch.convert('oklch').coords() c_str = f"oklch({ol*100:.1f}% {oc:.4f} {oh:.1f})" diff --git a/monobiome/plotting.py b/monobiome/plotting.py index 43274ca..788c463 100644 --- a/monobiome/plotting.py +++ b/monobiome/plotting.py @@ -5,6 +5,7 @@ import matplotlib.pyplot as plt from coloraide import Color from matplotlib.collections import LineCollection +from monobiome.util import srgb8_from_color from monobiome.palette import compute_hlc_map from monobiome.constants import ( h_map, @@ -87,7 +88,9 @@ def plot_hue_chroma_star() -> tuple[plt.Figure, plt.Axes]: _h = h_map[h_str] h_colors = [ - Color('oklch', [_l/100, _c, _h]).convert("srgb") + Color( + 'oklch', [_l/100, _c, _h] + ).convert("srgb").fit(method="oklch-chroma") for _l, _c in zip(L_points, Lpoints_Cstar, strict=True) ] @@ -124,7 +127,7 @@ def palette_image( h = row_count * cell_size w = max_cols * cell_size - img = np.ones((h, w, 3), float) + img = np.ones((h, w, 3), int) lightness_keys_per_row = [] @@ -133,8 +136,7 @@ def palette_image( lkeys = sorted(shades.keys()) lightness_keys_per_row.append(lkeys) for c, k in enumerate(lkeys): - col = Color(shades[k]).convert("srgb").fit(method="clip") - rgb = [col["r"], col["g"], col["b"]] + rgb = srgb8_from_color(shades[k]) r0, r1 = r * cell_size, (r + 1) * cell_size c0, c1 = c * cell_size, (c + 1) * cell_size img[r0:r1, c0:c1, :] = rgb @@ -156,7 +158,7 @@ def show_palette( if show_labels: fig, ax = plt.subplots(figsize=(fig_w, fig_h), dpi=dpi) - ax.imshow(img, interpolation="none", origin="upper") + ax.imshow(img, interpolation="nearest", origin="upper") ax.set_xticks([]) ytick_pos = [(i + 0.5) * cell_size for i in range(len(names))] diff --git a/monobiome/util.py b/monobiome/util.py index 9128649..dad0909 100644 --- a/monobiome/util.py +++ b/monobiome/util.py @@ -2,6 +2,7 @@ import math from types import GenericAlias from argparse import ArgumentParser, _SubParsersAction +import numpy as np from coloraide import Color _SubParsersAction.__class_getitem__ = classmethod(GenericAlias) @@ -33,3 +34,13 @@ def oklch_distance(xc: Color, yc: Color) -> float: dz = l1 - l2 return (dx**2 + dy**2 + dz**2)**0.5 + +def srgb8_from_color(c: str | Color) -> np.ndarray: + c = Color(c).convert("srgb").fit(method="oklch-chroma") + rgb = np.array([c["r"], c["g"], c["b"]], dtype=float) + rgb8 = np.clip(np.round(rgb * 255), 0, 255).astype(np.uint8) + + return rgb8 + +def hex_from_rgb8(rgb8: np.ndarray) -> str: + return f"#{int(rgb8[0]):02x}{int(rgb8[1]):02x}{int(rgb8[2]):02x}" diff --git a/scripts/prepare.sh b/scripts/prepare.sh index 2baa32e..89c025b 100755 --- a/scripts/prepare.sh +++ b/scripts/prepare.sh @@ -11,3 +11,6 @@ uv run monobiome palette -n oklch -f toml -o colors/oklch-palette.toml # generate provided app config "$script_dir/generate.sh" + +# generate release plots +uv run "$script_dir/plots.py"