Created
March 9, 2024 14:30
-
-
Save jmg-duarte/4d452d6aeaaed4b946c5a0281bedeebf to your computer and use it in GitHub Desktop.
Extract a black/white accent for a .colorset/Contents.json color
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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