"""XYB color space."""
from __future__ import annotations
from coloraide import algebra as alg
from coloraide.spaces import Space
from coloraide.types import Vector
from coloraide.cat import WHITES
from coloraide.channels import Channel, FLG_MIRROR_PERCENT
from coloraide import Color as Base
BIAS = 0.00379307325527544933
BIAS_CBRT = alg.nth_root(BIAS, 3)
LRGB_TO_LMS = [
[0.3, 0.622, 0.078],
[0.23, 0.692, 0.078],
[0.24342268924547819, 0.20476744424496821, 0.55180986650955360]
]
LMS_TO_LRGB = alg.inv(LRGB_TO_LMS)
def rgb_to_xyb(rgb: Vector) -> Vector:
"""Linear sRGB to XYB."""
lgamma, mgamma, sgamma = [alg.nth_root(c + BIAS, 3) - BIAS_CBRT for c in alg.dot(LRGB_TO_LMS, rgb)]
return [
(lgamma - mgamma) / 2,
(lgamma + mgamma) / 2,
sgamma
]
def xyb_to_rgb(xyb: Vector) -> Vector:
"""XYB to linear sRGB."""
x, y, sgamma = xyb
x *= 2
y *= 2
lgamma = (x + y) / 2
mgamma = y - lgamma
return alg.dot(LMS_TO_LRGB, [(c + BIAS_CBRT) ** 3 - BIAS for c in [lgamma, mgamma, sgamma]])
class XYB(Space):
"""XYB color class."""
BASE = 'srgb-linear'
NAME = "xyb"
SERIALIZE = ("--xyb",)
WHITE = WHITES['2deg']['D65']
# Range in Display-P3
CHANNELS = (
Channel("x", -0.02, 0.033),
Channel("y", 0.0, 0.845, flags=FLG_MIRROR_PERCENT),
Channel("b", 0.0, 0.845, flags=FLG_MIRROR_PERCENT)
)
def to_base(self, coords: Vector) -> Vector:
"""To XYB from base."""
return xyb_to_rgb(coords)
def from_base(self, coords: Vector) -> Vector:
"""From base to XYB."""
return rgb_to_xyb(coords)
class Color(Base): ...
Color.register(XYB())
Color('red').convert('xyb')
Color('white').convert('xyb')
Color('purple').convert('xyb')
Last active
April 14, 2023 16:57
-
-
Save facelessuser/c769cecafc8071de6f73da7dcd45f7ba to your computer and use it in GitHub Desktop.
XYB Notes
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment