ColorAide

repository·main·Indexed 43 days ago

https://github.com/facelessuser/coloraide

A pure Python, object-oriented library for accurate and flexible color manipulation. It supports modern CSS and various non-CSS color spaces, providing tools for color conversion, mixing, blending, interpolation, gamut mapping, and simulating color vision deficiency. Key features include the Color class for manipulation, ColorMatch for comparison, and a plugin API for extending color spaces.

Tokens
108.6K
Snippets
447
Records
544
Agent score
55%

What's inside ColorAide

  1. Introduction to ColorAide

    main

    ColorAide is a pure Python, object-oriented library for color manipulation. It focuses on color accuracy, proper round-tripping, and support for modern CSS color spaces as well as many non-CSS color spaces.

    Key capabilities include:

    • Converting colors between different color spaces.
    • Mixing and blending colors.
    • Interpolation and color distancing.
    • Gamut mapping and filters.
    • Simulating color vision deficiency.
    • Providing a plugin API for extending color spaces and utilities.
  2. What is ColorAide?

    main

    ColorAide is a pure Python, object-oriented color library designed for convenience and flexibility. It focuses on accurate color representation, proper round-tripping, and support for modern CSS color spaces and syntax.

    Key features include:

    • Support for modern CSS and non-CSS color spaces.
    • Utilities for interpolation, color distancing, blending, gamut mapping, filters, correlated color temperature, color vision deficiency simulation, and color harmonies.
    • A plugin API for extending color spaces and utilities.
    • Configurable defaults.

    Note: Because it is a pure Python, object-oriented library, there may be trade-offs in speed compared to libraries optimized solely for performance, but it prioritizes ease of use and flexibility.

    from coloraide import Color
    Color.steps(
        ['oklch(75% 30% 0)', 'oklch(75% 30% 360)'],
        steps=8,
        space='oklch',
        hue='longer'
    )
  3. What is the Gamut plugin and when to use it

    main

    The Gamut plugin provides an interface for handling special gamuts. Unlike standard color space gamuts, these represent calculated limits that are often difficult to work with directly (e.g., the Visible Spectrum).

    The plugin is used to:

    1. Check if a color falls within a specific special gamut.
    2. Force (fit) a color into a specific special gamut.

    Because the logic for checking and mapping these colors is specific to the gamut itself, the plugin acts as a bridge to specialized gamut-mapping algorithms.

  4. What is the Helmlab Metric color space?

    main

    Helmlab Metric is a color space specifically designed for perceptual distance measurements. It claims a STRESS score of 23.30 on COMBVD, which is 20% better than CIEDE2000.

    Important Usage Note: Helmlab Metric is intended for color distancing and is not meant to be used directly for interpolation or palette generation. For gradient and palette generation, use the Helmgen space instead.

    Properties

    • Name: helmlab-metric
    • White Point: D65 / 2˚ (Variant from ASTM-E308)
    • Coordinates:
      • l (lightness): [0, ~1.6]
      • a: [-1.5, 1.5]
      • b: [-1.5, 1.5]

    Note: The space is not strictly bound to these ranges; they are used as references for percentage inputs/outputs.

  5. CMYK color space properties and channel aliases

    main

    The CMYK color space is implemented based on sRGB primaries. It includes a blackness channel k in addition to the standard CMY channels.

    Properties:

    • White Point: D65 / 2˚
    • Coordinates Range: [0, 1] for all channels (supports extended range beyond gamut).

    Channel Aliases:

    ChannelAlias
    ccyan
    mmagenta
    yyellow
    kblack
  6. Configure RLAB viewing conditions

    main

    RLAB is a color-appearance space that depends on viewing environments. You can create custom RLAB variants by deriving from the RLAB class and defining a new Environment object.

    An Environment object controls how colors appear based on the following parameters:

    • white: The white point provided as (x, y) chromaticity coordinates.
    • adapting_luminance: The luminance of the adapting field (in cd/m2).
    • surround: The peripheral area description. Options include "dark" (e.g., movie theater), "dim" (e.g., bright TV in a dim room), or "average" (e.g., surface colors).
    • discounting: The degree of illuminant discounting. Options are "hard-copy" (full discount), "projected-transparency" (50% discount), or "soft-copy".

    Note: Using a discounting value other than "hard-copy" will result in non-zero chroma for achromatic colors (like white), as the model accounts for the eye not being fully adapted to the illuminant.

    from coloraide import Color as Base
    from coloraide.spaces.rlab import RLAB, Environment
    from coloraide.cat import WHITES
    import math
    
    class CustomRLAB(RLAB):
        NAME = "rlab-custom"
        SERIALIZE = ("--rlab-custom",)
        WHITE = WHITES['2deg']['D65']
        ENV = Environment(
            white=WHITE,
            adapting_luminance=64 / math.pi * 0.2,
            surround='average',
            discounting="soft-copy"
        )
    
    class Color(Base): ...
    
    Color.register([RLAB(), CustomRLAB()])
    
    # Now you can use the custom space
    Color('white').convert('rlab-custom')
  7. Handle undefined/NaN values in color channels

    main

    ColorAide uses coloraide.NaN (which is float('nan')) to represent undefined channels, such as a hue in an achromatic (zero saturation) HSL color.

    Linear Interpolation Behavior

    When performing linear interpolation between two colors:

    • If one color's channel is NaN, the result uses the value from the other color.
    • If both colors have NaN for the same channel, the result is NaN.

    Continuous and Cubic Spline Interpolation

    For continuous or cubic spline interpolation, NaN values are handled by looking at the wider context of multiple colors, meaning they may receive values from both sides of the interpolation point.

    Manual Manipulation

    You can manually set any channel to NaN to trigger this behavior.

    # Example: Mixing an achromatic color (NaN hue) with a colored one
    # The hue of the second color will be used because the first is undefined
    color = Color('white').convert('hsl')
    color2 = Color('green').convert('hsl')
    result = color.mix(color2, space="hsl")
    
    # Contrast: Manually setting hue to 0 instead of NaN changes the result
    color_with_hue = Color('white').convert('hsl').set('hue', 0)
    result_with_hue = color_with_hue.mix(color2, space="hsl")
  8. Use Adaptive Lightness in gamut mapping

    main

    Both minde-chroma and raytrace methods support Adaptive Lightness. This allows for non-constant lightness during chroma reduction, which can help preserve more colorfulness by sacrificing some lightness.

    To enable it, set the adaptive option in the fit method:

    • adaptive=0.0: Constant lightness (disables adaptive lightness).
    • adaptive > 0: Creates a bias towards a focal point of 50% lightness. A practical range is typically 0 to 0.5.
    # Using raytrace with adaptive lightness
    c.fit('srgb', method='raytrace', pspace='oklch', adaptive=0.5)
    
    # Using minde-chroma with adaptive lightness
    c.fit('srgb', method='minde-chroma', pspace='oklch', adaptive=0.5, jnd=0)
  9. Use the Rec. 709 color space

    main

    Rec. 709 (also known as BT.709 or ITU 709) is a standard for HDTV image encoding. It shares identical primary chromaticities and white points (D65 / 2˚) with sRGB, but uses a different transfer function (BT.1886 with a gamma of 2.4).

    Note: The Rec. 709 color space is not registered in the Color class by default and must be manually registered to be used via string parsing or standard constructors.

    Properties

    • Name: rec709
    • White Point: D65 / 2˚
    • Channel Aliases: r (or red), g (or green), b (or blue)
    • Coordinates Range: [0, 1] for r, g, and b (denoting in-gamut colors).
    # Note: Rec. 709 is not registered by default. You must register it first (see 'Registering Rec. 709' below).
  10. Use Mix-ins to inspect color space types

    main

    ColorAide uses mix-in classes to categorize color spaces into generic types. This allows you to write code that works across different color spaces by checking their type rather than their specific name. Common mix-ins include:

    • Cylindrical: Spaces with hue and radial components (e.g., HSL, HSV, HWB, LCh).
    • Luminant: Spaces with a lightness or luminance component (e.g., Lab, LCh, HSL).
    • Prism: 3D rectangular prism spaces.
    • RGBish: RGB-like spaces.
    • HSLish / HSVish / HWBish / Labish / LChish: Specialized categories.

    You can use isinstance(color._space, MixinClass) to determine if a color space supports specific generic behaviors, such as extracting hue or lightness.

    from coloraide.spaces import Labish
    srgb = Color('red')
    jzazbz = srgb.convert('jzazbz')
    
    for c in (srgb, jzazbz):
        if isinstance(c._space, Labish):
            # Access the lightness channel name and value generically
            l = c._space.names()[0]
            print('value: ', c.get(l))
  11. Use the Rec. 2100 PQ color space

    main

    Rec. 2100 PQ (BT.2100) is a color space designed for High Dynamic Range (HDR) television using the Perceptual Quantizer (PQ) transfer function. It utilizes the same wide color gamut as Rec. 2020.

    Properties:

    • Name: rec2100-pq
    • White Point: D65 / 2˚
    • Channel Ranges: r, g, and b are all in the range [0, 1].

    Note: rec2100-pq is registered in Color by default.

    from coloraide import Color
    
    # Creating a color in Rec. 2100 PQ
    color = Color("rec2100-pq", [0.5, 0.5, 0.5])