implement consistent quantization of srgb8 for palette figure

This commit is contained in:
2026-01-21 18:18:05 -08:00
parent a5256aaa62
commit b077e433cd
6 changed files with 27 additions and 7 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

@@ -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})"

View File

@@ -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))]

View File

@@ -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}"

View File

@@ -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"