# 3. API

The colorzero library includes a comprehensive `Color` class which is capable of converting between numerous color representations and calculating color differences. Various ancillary classes can be used to manipulate aspects of a color.

## 3.1. Color Class

This the primary class in the package, and often the only class you’ll need or want to interact with. It has an extremely flexible constructor, along with numerous explicit constructors, and attributes for conversion to other color systems.

class colorzero.Color(*args, **kwargs)

  The Color class is a tuple which represents a color as linear red, green, and blue components.

  The class has a flexible constructor which allows you to create an instance from any built-in color system. There are also explicit constructors for every known system that can convert (directly or indirectly) to linear RGB. For example, an instance of `Color` can be constructed in any of the following ways:

      >>> Color('#f00')
      <Color html='#ff0000' rgb=(1, 0, 0)>
      >>> Color('green')
      <Color html='#008000' rgb=(0.0, 0.501961, 0.0)>
      >>> Color(0, 0, 1)
      <Color html='#0000ff' rgb=(0, 0, 1)>
      >>> Color(h=0, s=1, v=0.5)
      <Color html='#800000' rgb=(0.5, 0, 0)>
      >>> Color(y=0.4, u=-0.05, v=0.615)
      <Color html='#ff104c' rgb=(1, 0.0626644, 0.298394)>

  The specific forms that the default constructor will accept are enumerated below:

  Style | Description
  --- | ---
  Single scalar parameter | Equivalent to calling `Color.from_string()`, or `Color.from_rgb24()`.
  Three positional parameters or a 3-tuple with no field names | Equivalent to calling `Color.from_rgb()` if all three parameters are between 0.0 and 1.0, or `Color.from_rgb_bytes()` otherwise.
  Three named parameters, or a 3-tuple with fields “r”, “g”, “b”
  Three named parameters, or a 3-tuple with fields “red”, “green”, “blue”
  Three named parameters, or a 3-tuple with fields “y”, “u”, “v” | Equivalent to calling `Color.from_yuv()` if “y” is between 0.0 and 1.0, “u” is between -0.436 and 0.436, and “v” is between -0.615 and 0.615, or `Color.from_yuv_bytes()` otherwise.
  Three named parameters, or a 3-tuple with fields “y”, “i”, “q” | Equivalent to calling `Color.from_yiq()`.
  Three named parameters, or a 3-tuple with fields “h”, “l”, “s” | Equivalent to calling `Color.from_hls()`.
  Three named parameters, or a 3-tuple with fields “hue”, “lightness”, “saturation”
  Three named parameters, or a 3-tuple with fields “h”, “s”, “v” | Equivalent to calling `Color.from_hsv()`
  Three named parameters, or a 3-tuple with fields “hue”, “saturation”, “value”
  Three named parameters, or a 3-tuple with fields “x”, “y”, “z” | Equivalent to calling `Color.from_xyz()`
  Three named parameters, or a 3-tuple with fields “l”, “a”, “b” | Equivalent to calling `Color.from_lab()`
  Three named parameters, or a 3-tuple with fields “l”, “u”, “v” | Equivalent to calling `Color.from_luv()`

  If the constructor parameters do not conform to any of the variants in the table above, a `ValueError` will be raised.

  Internally, the color is always represented as 3 `float` values corresponding to the red, green, and blue components of the color. These values take a value from 0.0 to 1.0 (least to full intensity). The class provides several attributes which can be used to convert one color system into another:

      >>> Color('#f00').hls
      HLS(h=0.0, l=0.5, s=1.0)
      >>> Color.from_string('green').hue
      Hue(deg=120.0)
      >>> Color.from_rgb_bytes(0, 0, 255).yuv
      YUV(y=0.114, u=0.436, v=-0.10001426533523537)

  As `Color` derives from tuple, instances are immutable. While this provides the advantage that they can be used in a `set` or as keys of a `dict`, it does mean that colors themselves cannot be directly manipulated (e.g. by setting the red component).

  However, several auxilliary classes in the module provide the ability to perform simple transformations of colors via operators which produce a new `Color` instance. For example, you can add, subtract, and multiply colors directly:

      >>> Color('red') + Color('blue')
      <Color html='#ff00ff' rgb=(1, 0, 1)>
      >>> Color('magenta') - Color('red')
      <Color html='#0000ff' rgb=(0, 0, 1)>

  Values are clipped to ensure the resulting color is still valid:

      >>> Color('#ff00ff') + Color('#ff0000')
      <Color html='#ff00ff' rgb=(1, 0, 1)>

  You can wrap numbers in constructors like `Red` (or obtain elements of existing colors), then add, subtract, or multiply them with a `Color`:

      >>> Color('red') - Red(0.5)
      <Color html='#800000' rgb=(0.5, 0, 0)>
      >>> Color('green') + Color('grey').red
      <Color html='#808000' rgb=(0.501961, 0.501961, 0)>

  You can even manipulate non-primary attributes like hue, saturation, and lightness with standard addition, subtraction or multiplication operators:

      >>> Color.from_hls(0.5, 0.5, 1.0)
      <Color html='#00ffff' rgb=(0, 1, 1)>
      >>> Color.from_hls(0.5, 0.5, 1.0) * Lightness(0.8)
      <Color html='#00cccc' rgb=(0, 0.8, 0.8)>
      >>> (Color.from_hls(0.5, 0.5, 1.0) * Lightness(0.8)).hls
      HLS(h=0.5, l=0.4, s=1.0)

  In the last example above, a `Color` instance is constructed from HLS (hue, lightness, saturation) values with a lightness of 0.5. This is multiplied by a `Lightness` a value of 0.8 which constructs a new `Color` with the same hue and saturation, but a lightness of 0.4 (0.8 × 0.5).

  If an instance is converted to a string (with `str()`) it will return a string containing the 7-character HTML code for the color (e.g. “#ff0000” for red). As can be seen in the examples above, a similar representation is included for the output of `repr()`. The output of `repr()` can be customized by assigning values to `Color.repr_style`.

  red

    Return the red value as a `Red` instance

  green

    Return the green value as a `Green` instance

  blue

    Return the blue value as a `Blue` instance

  repr_style

    Specifies the style of output returned when using `repr()` against a `Color` instance. This is an attribute of the class, not of instances. For example:

        >>> Color('#f00')
        <Color html='#ff0000' rgb=(1, 0, 0)>
        >>> Color.repr_style = 'html'
        >>> Color('#f00')
        Color('#ff0000')

    The following values are valid:

    - ‘default’ - The style shown above

    - ‘term16m’ - Similar to the default style, but instead of the HTML style being included, a swatch previewing the color is output. Note that the terminal must support 24-bit color ANSI codes for this to work.

    - ‘term256’ - Similar to ‘termtrue’, but uses the closest color that can be found in the standard 256-color xterm palette. Note that the terminal must support 8-bit color ANSI codes for this to work.

    - ‘html’ - Outputs a valid `Color` constructor using the HTML style, e.g. `Color('#ff99bb')`

    - ‘rgb’ - Outputs a valid `Color` constructor using the floating point RGB values, e.g. `Color(1, 0.25, 0)`

## 3.2. Format Strings

Instances of `Color` can be used in format strings to output various representations of a color, including HTML sequences and ANSI escape sequences to color terminal output. Format specifications can be used to modify the output to support different terminal types. For example:

    >>> red = Color('red')
    >>> green = Color('green')
    >>> blue = Color('#47b')
    >>> print("{red:html}".format(red=red))
    #ff0000
    >>> print(repr("{red}Red{red:0} Alert!".format(red=red)))
    '\\x1b[1;31mRed\\x1b[0m Alert!'
    >>> print(repr("The grass is {green:16m}greener{green:0}.".format(
    ... green=green)))
    'The grass is \\x1b[38;2;0;128;0mgreener\\x1b[0m.'
    >>> print(repr("{blue:b16m}Blue skies{blue:0}".format(blue=blue)))
    '\\x1b[48;2;68;119;187mBlue skies\\x1b[0m'

The format specification is one of:

- “html” - the color will be output as the common 7-character HTML represention of #RRGGBB where RR, GG, and BB are the red, green and blue components expressed as a single hexidecimal byte

- “css” or “cssrgb” - the color will be output in CSS’ functional notation rgb(r, g, b) where r, g, and b are decimal representations of the red, green, and blue components in the range 0 to 255

- “csshsl” - the color will be output in CSS’ function notation hue(hdeg, s%, l%) where h, s, and l are the hue (expressed in degrees), saturation, and lightness (expressed as percentages)

- One of the ANSI format specifications which consist of an optional foreground / background specifier (the letters “f” or “b”) followed by an optional terminal type identifer, which is one of:

  - “8” - the default, indicating only the original 8 DOS colors are supported (technically, 16 foreground colors are supported via use of the “bold” style for “intense” colors)

  - “256” - indicates the terminal supports 256 colors via 8-bit color ANSI codes

  - “16m” - indicating the terminal supports ~16 million colors via 24-bit color ANSI codes

Alternately, “0” can be specified indicating that the style should be reset. If specified with the optional foreground / background specifier, “0” resets only the foreground / background color. If specified alone it resets all styles. More formally:

    <term_fore_back> ::= "" | "f" | "b"
    <term_type>      ::= "" | "0" | "8" | "256" | "16m"
    <term>           ::= <term_fore_back> <term_type>
    <html>           ::= "html"
    <css>            ::= "css" ("rgb" | "hsl")?
    <format_spec>    ::= <html> | <css> | <term>

Added in version 1.1: The ability to output ANSI codes via format strings, and the customization of `repr()` output.

Added in version 1.2: The ability to output HTML and CSS representations via format strings

## 3.3. Manipulation Classes

These manipulation classes are used in conjunction with the standard arithmetic addition, subtraction, and multiplication operators to calculate new `Color` instances.

class colorzero.Red(x=0, /)

  Represents the red component of a `Color` for use in transformations. Instances of this class can be constructed directly with a float value, or by querying the `Color.red` attribute. Addition, subtraction, and multiplication are supported with `Color` instances. For example:

      >>> Color.from_rgb(0, 0, 0) + Red(0.5)
      <Color html='#800000' rgb=(0.5, 0, 0)>
      >>> Color('#f00') - Color('#900').red
      <Color html='#660000' rgb=(0.4, 0, 0)>
      >>> (Red(0.1) * Color('red')).red
      Red(0.1)

class colorzero.Green(x=0, /)

  Represents the green component of a `Color` for use in transformations. Instances of this class can be constructed directly with a float value, or by querying the `Color.green` attribute. Addition, subtraction, and multiplication are supported with `Color` instances. For example:

      >>> Color(0, 0, 0) + Green(0.1)
      <Color html='#001a00' rgb=(0, 0.1, 0)>
      >>> Color.from_yuv(1, -0.4, -0.6) - Green(1)
      <Color html='#510030' rgb=(0.316098, 0, 0.187156)>
      >>> (Green(0.5) * Color('white')).rgb
      RGB(r=1.0, g=0.5, b=1.0)

class colorzero.Blue(x=0, /)

  Represents the blue component of a `Color` for use in transformations. Instances of this class can be constructed directly with a float value, or by querying the `Color.blue` attribute. Addition, subtraction, and multiplication are supported with `Color` instances. For example:

      >>> Color(0, 0, 0) + Blue(0.2)
      <Color html='#000033' rgb=(0, 0, 0.2)>
      >>> Color.from_hls(0.5, 0.5, 1.0) - Blue(1)
      <Color html='#00ff00' rgb=(0, 1, 0)>
      >>> Blue(0.9) * Color('white')
      <Color html='#ffffe6' rgb=(1, 1, 0.9)>

class colorzero.Hue(n=None, deg=None, rad=None)

  Represents the hue of a `Color` for use in transformations. Instances of this class can be constructed directly with a float value in the range [0.0, 1.0) representing an angle around the HSL hue wheel. As this is a circular mapping, 0.0 and 1.0 effectively mean the same thing, i.e. out of range values will be normalized into the range [0.0, 1.0).

  The class can also be constructed with the keyword arguments `deg` or `rad` if you wish to specify the hue value in degrees or radians instead, respectively. Instances can also be constructed by querying the `Color.hue` attribute.

  Addition, subtraction, and multiplication are supported with `Color` instances. For example:

      >>> Color(1, 0, 0).hls
      HLS(h=0.0, l=0.5, s=1.0)
      >>> (Color(1, 0, 0) + Hue(deg=180)).hls
      HLS(h=0.5, l=0.5, s=1.0)

  Note that whilst multiplication by a `Hue` doesn’t make much sense, it is still supported. However, the circular nature of a hue value can lead to suprising effects. In particular, since 1.0 is equivalent to 0.0 the following may be observed:

      >>> (Hue(1.0) * Color.from_hls(0.5, 0.5, 1.0)).hls
      HLS(h=0.0, l=0.5, s=1.0)

class colorzero.Saturation(x=0, /)

  Represents the saturation of a `Color` for use in transformations. Instances of this class can be constructed directly with a float value, or by querying the `Color.saturation` attribute. Addition, subtraction, and multiplication are supported with `Color` instances. For example:

      >>> Color(0.9, 0.9, 0.6) + Saturation(0.1)
      <Color html='#ecec93' rgb=(0.925, 0.925, 0.575)>
      >>> Color('red') - Saturation(1)
      <Color html='#808080' rgb=(0.5, 0.5, 0.5)>
      >>> Saturation(0.5) * Color('wheat')
      <Color html='#e4d9c3' rgb=(0.896078, 0.85098, 0.766667)>

class colorzero.Lightness(x=0, /)

  Represents the lightness of a `Color` for use in transformations. Instances of this class can be constructed directly with a float value, or by querying the `Color.lightness` attribute. Addition, subtraction, and multiplication are supported with `Color` instances. For example:

      >>> Color(0, 0, 0) + Lightness(0.1)
      <Color html='#1a1a1a' rgb=(0.1, 0.1, 0.1)>
      >>> Color.from_rgb_bytes(0x80, 0x80, 0) - Lightness(0.2)
      <Color html='#1a1a00' rgb=(0.101961, 0.101961, 0)>
      >>> Lightness(0.9) * Color('wheat')
      <Color html='#f0ce8e' rgb=(0.94145, 0.806785, 0.555021)>

class colorzero.Luma(x=0, /)

  Represents the luma of a `Color` for use in transformations. Instances of this class can be constructed directly with a float value, or by querying the `Color.yuv.y` attribute. Addition, subtraction, and multiplication are supported with `Color` instances. For example:

      >>> Color(0, 0, 0) + Luma(0.1)
      <Color html='#1a1a1a' rgb=(0.1, 0.1, 0.1)>
      >>> Color('red') * Luma(0.5)
      <Color html='#d90000' rgb=(0.8505, 0, 0)>

## 3.4. Difference Functions

colorzero.euclid(color1, color2)

  Calculates color difference as a simple Euclidean distance by treating the three components as spatial dimensions.

  Note

  This function will return considerably different values to the other difference functions. In particular, the maximum “difference” will be \(\sqrt{3}\) which is much smaller than the output of the CIE functions.

colorzero.cie1976(color1, color2)

  Calculates color difference according to the CIE 1976 formula. Effectively this is the Euclidean formula, but with CIE L*a*b* components instead of RGB.

colorzero.cie1994g(color1, color2)

  Calculates color difference according to the CIE 1994 formula with the “textile” bias. See `cie1994()` for further information.

colorzero.cie1994t(color1, color2)

  Calculates color difference according to the CIE 1994 formula with the “graphics” bias. See `cie1994()` for further information.

colorzero.ciede2000(color1, color2)

  Calculates color difference according to the CIEDE 2000 formula. This is the most accurate algorithm currently implemented but also the most complex and slowest. Like CIE1994 it is largely based in CIE L*C*h* space, but with several modifications to account for perceptual uniformity flaws.

## 3.5. Easing Functions

These functions can be used with the `Color.gradient()` method to control the progression of the fade between the two colors.

colorzero.linear(steps)

  Linear easing function; yields steps values between 0.0 and 1.0

colorzero.ease_in(steps)

  Quadratic ease-in function; yields steps values between 0.0 and 1.0

colorzero.ease_out(steps)

  Quadratic ease-out function; yields steps values between 0.0 and 1.0

colorzero.ease_in_out(steps)

  Quadratic ease-in-out function; yields steps values between 0.0 and 1.0