implement consistent quantization of srgb8 for palette figure
This commit is contained in:
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 |
@@ -5,6 +5,10 @@ from importlib.metadata import version
|
|||||||
|
|
||||||
from coloraide import Color
|
from coloraide import Color
|
||||||
|
|
||||||
|
from monobiome.util import (
|
||||||
|
hex_from_rgb8,
|
||||||
|
srgb8_from_color,
|
||||||
|
)
|
||||||
from monobiome.constants import (
|
from monobiome.constants import (
|
||||||
h_map,
|
h_map,
|
||||||
L_points,
|
L_points,
|
||||||
@@ -24,8 +28,8 @@ def compute_hlc_map(notation: str) -> dict[str, Any]:
|
|||||||
oklch = Color('oklch', [_l/100, _c, _h])
|
oklch = Color('oklch', [_l/100, _c, _h])
|
||||||
|
|
||||||
if notation == "hex":
|
if notation == "hex":
|
||||||
srgb = oklch.convert('srgb')
|
rgb8 = srgb8_from_color(oklch)
|
||||||
c_str = srgb.to_string(hex=True)
|
c_str = hex_from_rgb8(rgb8)
|
||||||
elif notation == "oklch":
|
elif notation == "oklch":
|
||||||
ol, oc, oh = oklch.convert('oklch').coords()
|
ol, oc, oh = oklch.convert('oklch').coords()
|
||||||
c_str = f"oklch({ol*100:.1f}% {oc:.4f} {oh:.1f})"
|
c_str = f"oklch({ol*100:.1f}% {oc:.4f} {oh:.1f})"
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import matplotlib.pyplot as plt
|
|||||||
from coloraide import Color
|
from coloraide import Color
|
||||||
from matplotlib.collections import LineCollection
|
from matplotlib.collections import LineCollection
|
||||||
|
|
||||||
|
from monobiome.util import srgb8_from_color
|
||||||
from monobiome.palette import compute_hlc_map
|
from monobiome.palette import compute_hlc_map
|
||||||
from monobiome.constants import (
|
from monobiome.constants import (
|
||||||
h_map,
|
h_map,
|
||||||
@@ -87,7 +88,9 @@ def plot_hue_chroma_star() -> tuple[plt.Figure, plt.Axes]:
|
|||||||
|
|
||||||
_h = h_map[h_str]
|
_h = h_map[h_str]
|
||||||
h_colors = [
|
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)
|
for _l, _c in zip(L_points, Lpoints_Cstar, strict=True)
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -124,7 +127,7 @@ def palette_image(
|
|||||||
|
|
||||||
h = row_count * cell_size
|
h = row_count * cell_size
|
||||||
w = max_cols * 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 = []
|
lightness_keys_per_row = []
|
||||||
|
|
||||||
@@ -133,8 +136,7 @@ def palette_image(
|
|||||||
lkeys = sorted(shades.keys())
|
lkeys = sorted(shades.keys())
|
||||||
lightness_keys_per_row.append(lkeys)
|
lightness_keys_per_row.append(lkeys)
|
||||||
for c, k in enumerate(lkeys):
|
for c, k in enumerate(lkeys):
|
||||||
col = Color(shades[k]).convert("srgb").fit(method="clip")
|
rgb = srgb8_from_color(shades[k])
|
||||||
rgb = [col["r"], col["g"], col["b"]]
|
|
||||||
r0, r1 = r * cell_size, (r + 1) * cell_size
|
r0, r1 = r * cell_size, (r + 1) * cell_size
|
||||||
c0, c1 = c * cell_size, (c + 1) * cell_size
|
c0, c1 = c * cell_size, (c + 1) * cell_size
|
||||||
img[r0:r1, c0:c1, :] = rgb
|
img[r0:r1, c0:c1, :] = rgb
|
||||||
@@ -156,7 +158,7 @@ def show_palette(
|
|||||||
if show_labels:
|
if show_labels:
|
||||||
fig, ax = plt.subplots(figsize=(fig_w, fig_h), dpi=dpi)
|
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([])
|
ax.set_xticks([])
|
||||||
|
|
||||||
ytick_pos = [(i + 0.5) * cell_size for i in range(len(names))]
|
ytick_pos = [(i + 0.5) * cell_size for i in range(len(names))]
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import math
|
|||||||
from types import GenericAlias
|
from types import GenericAlias
|
||||||
from argparse import ArgumentParser, _SubParsersAction
|
from argparse import ArgumentParser, _SubParsersAction
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
from coloraide import Color
|
from coloraide import Color
|
||||||
|
|
||||||
_SubParsersAction.__class_getitem__ = classmethod(GenericAlias)
|
_SubParsersAction.__class_getitem__ = classmethod(GenericAlias)
|
||||||
@@ -33,3 +34,13 @@ def oklch_distance(xc: Color, yc: Color) -> float:
|
|||||||
dz = l1 - l2
|
dz = l1 - l2
|
||||||
|
|
||||||
return (dx**2 + dy**2 + dz**2)**0.5
|
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}"
|
||||||
|
|||||||
@@ -11,3 +11,6 @@ uv run monobiome palette -n oklch -f toml -o colors/oklch-palette.toml
|
|||||||
|
|
||||||
# generate provided app config
|
# generate provided app config
|
||||||
"$script_dir/generate.sh"
|
"$script_dir/generate.sh"
|
||||||
|
|
||||||
|
# generate release plots
|
||||||
|
uv run "$script_dir/plots.py"
|
||||||
|
|||||||
Reference in New Issue
Block a user