Skip to content

Instantly share code, notes, and snippets.

@jmg-duarte
Created March 9, 2024 14:30
Show Gist options
  • Save jmg-duarte/4d452d6aeaaed4b946c5a0281bedeebf to your computer and use it in GitHub Desktop.
Save jmg-duarte/4d452d6aeaaed4b946c5a0281bedeebf to your computer and use it in GitHub Desktop.
Extract a black/white accent for a .colorset/Contents.json color
import json
from typing import Any, Tuple
type RGB = Tuple[int, int, int]
type RGBA = Tuple[int, int, int, int]
def rgba_to_rgb(foreground: RGBA, background: RGB) -> RGB:
(fg_r, fg_g, fg_b, fg_a) = foreground
(bg_r, bg_g, bg_b) = background
a = fg_a / 255
inv_a = 1 - a
return (
round(inv_a * bg_r + a * fg_r),
round(inv_a * bg_g + a * fg_g),
round(inv_a * bg_b + a * fg_b),
)
def sRGB(c: int) -> float:
c_ = c / 255
if c_ <= 0.03928:
return c_ / 12.92
else:
return pow((c_ + 0.055) / 1.055, 2.4)
def luminance(c: RGB) -> float:
r, g, b = c
return 0.2126 * sRGB(r) + 0.7152 * sRGB(g) + 0.0722 * sRGB(b)
def contrast(fg: RGB, bg: RGB) -> float:
fg_l = luminance(fg)
bg_l = luminance(bg)
return (max(fg_l, bg_l) + 0.05) / (min(fg_l, bg_l) + 0.05)
def accent(c: RGB) -> RGB:
on_white = contrast(c, (255, 255, 255))
on_black = contrast(c, (0, 0, 0))
if on_white > on_black:
return (0xFF, 0xFF, 0xFF)
else:
return (0x00, 0x00, 0x00)
def hex_to_rgb(h: str) -> RGB:
return int(h[0:2], 16), int(h[2:4], 16), int(h[4:6], 16)
def from_apple_colorset(path: str) -> RGBA:
with open(path) as f:
colorset: dict[str, Any] = json.load(f)
components = colorset["colors"][0]["color"]["components"]
return (
int(components["red"], 16),
int(components["green"], 16),
int(components["blue"], 16),
int(float(components["alpha"]) * 255),
)
paths = [
".../Color.colorset/Contents.json"
]
white: list[str] = []
black: list[str] = []
for path in paths:
color_name = path.rsplit("/", 2)[-2].split(".")[0]
if " " in color_name:
first, second = color_name.split()
color_name = first.lower() + second
else:
color_name = color_name.lower()
color = from_apple_colorset(path)
a = accent(color[0:3])
if a == (0, 0, 0):
black.append(color_name)
else:
white.append(color_name)
print(f"case {", ".join(("." + b for b in black))}: .black")
print(f"case {", ".join(("." + w for w in white))}: .white")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment