Last active
February 18, 2022 17:16
-
-
Save facelessuser/f7adf843a4f82b049a3de00dc16a07a8 to your computer and use it in GitHub Desktop.
CSS Level 4 Gamut mapping
This file contains 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, clip_channels | |
from coloraide.util import NaN | |
class OklchChroma(Fit): | |
"""Lch chroma gamut mapping class.""" | |
NAME = "oklch-chroma" | |
EPSILON = 0.0001 | |
LIMIT = 0.02 | |
DE = "ok" | |
SPACE = "oklch" | |
SPACE_COORDINATE = "{}.chroma".format(SPACE) | |
MIN_LIGHTNESS = 0 | |
MAX_LIGHTNESS = 1 | |
@classmethod | |
def fit(cls, color, **kwargs): | |
""" | |
Gamut mapping via Oklch chroma. | |
""" | |
space = color.space() | |
mapcolor = color.convert(cls.SPACE) | |
lightness = mapcolor.lightness | |
# Return white or black if lightness is out of range | |
if lightness >= cls.MAX_LIGHTNESS or lightness <= cls.MIN_LIGHTNESS: | |
mapcolor.chroma = 0 | |
mapcolor.hue = NaN | |
clip_channels(color.update(mapcolor)) | |
return | |
# Set initial chroma boundaries | |
low = 0.0 | |
high = mapcolor.chroma | |
clip_channels(color.update(mapcolor)) | |
# Adjust chroma (using binary search). | |
# This helps preserve the other attributes of the color. | |
# Compress chroma until we are are right at the JND edge of being out of gamut. | |
if not mapcolor.in_gamut(space): | |
while True: | |
mapcolor.chroma = (high + low) * 0.5 | |
if mapcolor.in_gamut(space, tolerance=0): | |
low = mapcolor.chroma | |
else: | |
clip_channels(color.update(mapcolor)) | |
if mapcolor.delta_e(color, method=cls.DE) < cls.LIMIT: | |
break | |
high = mapcolor.chroma | |
class Color2(Color): ... | |
Color2.register(OklchChroma, overwrite=True) | |
Color('green').interpolate('blue') | |
Color2('green').interpolate('blue') | |
Color('red').interpolate('blue', space="oklch") | |
Color2('red').interpolate('blue', space="oklch") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment