Created
February 26, 2024 18:13
-
-
Save facelessuser/e5144f6846c83e24f0c5619fc82ee45d to your computer and use it in GitHub Desktop.
Compare GMA
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
from coloraide.gamut import Fit | |
from coloraide.spaces import RGBish | |
from coloraide import algebra as alg | |
class OkLChScale(Fit): | |
""" | |
Gamut mapping by scaling. | |
Expected gamut mapping spaces are RGB type spaces. | |
For best results, linear light RGB spaces are preferred. | |
""" | |
NAME = "oklch-scale" | |
SPACE = "oklch" | |
def fit(self, color, space, **kwargs): | |
"""Scale the color within its gamut but preserve L and h as much as possible.""" | |
# Requires an RGB-ish space, preferably a linear space. | |
if not isinstance(color.CS_MAP[space], RGBish): | |
raise ValueError("Scaling only works in an RGBish color space, not {}".format(type(color.CS_MAP[space]))) | |
# For now, if a non-linear CSS variant is specified, just use the linear form. | |
if space in {'srgb', 'display-p3', 'rec2020', 'a98-rgb', 'prophoto-rgb'}: | |
space += '-linear' | |
orig = color.space() | |
mapcolor = color.convert(self.SPACE, norm=False) if orig != self.SPACE else color.clone().normalize(nans=False) | |
gamutcolor = color.convert(space, norm=False) if orig != space else color.clone().normalize(nans=False) | |
self.scale(gamutcolor) | |
gamutcolor.set( | |
{ | |
self.SPACE + '.l': mapcolor['l'], | |
self.SPACE + '.h': mapcolor['h'] | |
} | |
) | |
self.scale(gamutcolor) | |
color.update(gamutcolor) | |
def scale(self, color): | |
"""Scale the RGB color within its gamut.""" | |
deltas = [c - 0.5 for c in color[:-1]] | |
max_distance = max(abs(c) for c in deltas) | |
scalingFactor = max_distance / 0.5; | |
color[:-1] = [c / scalingFactor + 0.5 for c in deltas] | |
class ColorScale(Color): | |
FIT = 'oklch-scale' | |
ColorScale.register(OkLChScale()) | |
class ColorRayTrace(Color): | |
FIT = 'oklch-raytrace' | |
class ColorCSS(Color): | |
FIT = 'oklch-chroma' | |
ColorScale.interpolate(['red', 'green'], space='oklch') | |
ColorRayTrace.interpolate(['red', 'green'], space='oklch') | |
ColorCSS.interpolate(['red', 'green'], space='oklch') | |
ColorScale.interpolate(['white', 'blue'], space='oklch') | |
ColorRayTrace.interpolate(['white', 'blue'], space='oklch') | |
ColorCSS.interpolate(['white', 'blue'], space='oklch') | |
ColorScale.interpolate(['oklch(20% 0.8 0)', 'oklch(20% 0.8 360)'], space='oklch', hue='longer') | |
ColorRayTrace.interpolate(['oklch(20% 0.8 0)', 'oklch(20% 0.8 360)'], space='oklch', hue='longer') | |
ColorCSS.interpolate(['oklch(20% 0.8 0)', 'oklch(20% 0.8 360)'], space='oklch', hue='longer') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment