Graphics::Toolkit::Color(3)

NAME
Graphics::Toolkit::Color - calculate color (sets), IO many spaces and formats

SYNOPSIS
    use Graphics::Toolkit::Color qw/color is_in_gamut/;

    my $red = Graphics::Toolkit::Color->new('red');  # create color object
    say $red->add_value( 'blue' => 255 )->name;      # red + blue = 'magenta'
    my @blue = color( 0, 0, 255)->values('HSL');     # 240, 100, 50 = blue
    if (is_in_gamut('oklab(14, -106, 3)')) { ..      # check if valid
    $red->mix( to => [HSL => 0,0,80], by => 0.1);     # mix red with a little grey
    $red->gradient( to => '#0000FF', steps => 10);   # 10 colors from red to blue
    my @base_triadic = $red->complement( 3 );        # get fitting red green and blue
    my @reds = $red->cluster( r => 1.1, min_d => 1 );# 13 shades of red

DESCRIPTION
Graphics::Toolkit::Color, for short GTC, is the top level API of this library and the only package a regular user should be concerned with. Its main purpose is the creation of related colors or sets of them, such as gradients, complements and more. But if you want to convert, quantize, round or reformat color definitions or translate from and to color names, it can be helpful too.

This page will give you a quick overview of all GTC methods. The Manual contains deeper explanations and describes every argument and topic of interest in detail. Therefore each chapter here starts with a link to the appropriate paragraph of a manual page.

While this module can understand and output color values of many (33) color spaces, RGB is the internal and primary one for input and output, because GTC is about colors that can be shown on the screen, and these are usually encoded in RGB (nonlinear standard RGB). However, many color calculations are operating by default in OKLAB or OKHSL to give perceptually uniform results.

Each GTC object represents one color and is read-only. It has no runtime dependencies. Only Test::Simple and Test::Warn are needed for testing. The behavior of error messages can be chosen, but defaults to using Carp.

DEPRECATION
The next API cleanup will come with version 3.0. Please see which syntax is on the way out.

CONSTRUCTOR
new is the universal constructor to create a GTC object that takes the arguments: color (color definition), raw (defaults to false, which clamps values into range), range (min. and max. values) and in (color space name). "color" is the only required argument and the default argument (can be provided as the only positional argument).

The importable method color is a short alias for calling "new" just with the argument "color".

    use Graphics::Toolkit::Color qw/color/;

    my $color = Graphics::Toolkit::Color->new( 'Emerald' ); # X11 constant
    my $green = Graphics::Toolkit::Color->new( 'SVG:green');# SVG constant (explicit with full name)
    my $navy  = color( 'navy' );                            # just a shortcut, X11 constant

    color(  r => 255, g => 0, b => 0 );                     # red (RGB)
    color( {r => 255, g => 0, b => 0});                     # red in char_hash format (RGB)
    color( Red => 255, Green => 0, Blue => 0);              # red in hash format (RGB)
    color( Hue => 0, Saturation => 1, Lightness => .5 );    # red in OKHSL
    color( hue => 0, whiteness => 0, blackness => 0 );      # red in OKHWB

    color(  255, 0, 0 );                # list format, no space name -> RGB
    color( [255, 0, 0] );               # array format, RGB only (as input)
    color( 'RGB',   255, 0, 0  );       # named list format
    color(  RGB =>  255, 0, 0  );       # with fat comma
    color( [RGB =>  255, 0, 0] );       # named_array
    color(  RGB => [255, 0, 0] );       # tuple under named key
    color( [RGB => [255, 0, 0]]);       # nested_array

    color( 'rgb: 255, 0, 0' );          # named string format, commas are not optional
    color( 'HSV: 240, 100, 100' );      # space name is case insensitive
    color( 'hsv(240, 100, 100)' );      # css_string format
    color( 'hsv(240, 100%, 100%)' );    # value suffix is optional
    color( 'rgb(255 0 0)' );            # commas are optional

    color( '#FF0000' );                 # hex_string format, RGB only
    color( '#f00' );                    # hex_string format, short form

    # color is far outside the RGB16 range, but will be read as is, unclamped
    Graphics::Toolkit::Color->new( color => [100_000,0,0], range => 2**16-1, raw => 1 );

GETTER
These methods provide information about color(s), but not a GTC object.

  is_in_gamut
is_in_gamut returns a perlish pseudo boolean that answers the question: is this color inside the value range of a color space (gamut). It can be used as a method or an importable subroutine. In method mode it takes one optional positional argument, which is a color space name (like in). The color will be converted into that space, before a check is performed. If no space name is provided, the check happens in the color space the original values (when the object was created) were defined in.

When used as a subroutine, it requires only one positional argument, that has to be a color definition (like with the "color" routine). This check will be performed in the color space the color is defined in. For color names this would be RGB, which makes the result always true (1).

    $color->is_in_gamut( 'okLab');               # is current color inside OKLAB?

    use Graphics::Toolkit::Color qw/is_in_gamut/;
    is_in_gamut('rgb: 0, 0, 300');               # false, SRGB ranges span up to 255
    is_in_gamut('#000000');                      # true, black is always included

  values
values returns the numeric values of the color, held by the object and accepts six optional, named arguments: in (color space), "as" ( format), range (min. and max. values), "precision", "suffix" and raw (defaults to false, which clamps values into range). "in" is the default argument (used as only positional) and if no arguments are provided, the method will return a list with RGB values.

    $blue->values();                                        #  0, 0, 255
    $blue->values( in => 'RGB', as => 'list');              #  0, 0, 255  # explicit arguments
    $blue->values(              as => 'array');             # [0, 0, 255] - RGB only
    $blue->values( in => 'RGB', as => 'named_array');       # ['RGB', 0, 0, 255]
    $blue->values( in => 'RGB', as => 'hash');              # { red => 0, green => 0, blue => 255}
    $blue->values( in => 'RGB', as => 'char_hash');         # { r => 0, g => 0, b => 255}
    $blue->values( in => 'RGB', as => 'named_string');      # 'rgb: 0, 0, 255'
    $blue->values( in => 'RGB', as => 'css_string');        # 'rgb( 0, 0, 255)'
    $blue->values(              as => 'hex_string');        # '#0000ff' - RGB only
    $blue->values(           range => 2**16-1 );            # 0, 0, 65535
    $blue->values('HSL');                                   # 240, 100, 50 # HSL is only argument
    $blue->values( in => 'HSL',suffix => ['', '%','%']);    # 240, '100%', '50%'
    $blue->values( in => 'HSB',  as => 'hash')->{'hue'};    # 240
   ($blue->values( 'HSB'))[0];                              # 240
    $blue->values( in => 'XYZ', range => 1, precision => 2);# normalized, 2 decimals max.

  name
name returns the normalized name of the current color, if it (converted to RGB) is part of a color scheme. It has four optional named arguments: from (scheme name), "all" (allows to return more names), "full" (include scheme name in color name) and "distance" (all colors within distance). The default argument is "from" which defaults to the default scheme. All other arguments default to zero.

    $blue->name();                                   # 'blue'
    $blue->name('SVG');                              # 'blue'
    $blue->name( from => [qw/CSS X/], all => 1);     # 'blue', 'blue1'
    $blue->name( from => 'CSS', full => 1);          # 'CSS:blue'
    $blue->name( distance => 3, all => 1);           # all names within the distance

  closest_name
closest_name (almost) always returns a normalized color name (unlike name). In list context it also returns the "distance" between the current color and the color belonging to the returned name. It has three optional, named arguments: "from", "all", "full" which work the same way as in "name".

    my $name = $red_like->closest_name;              # closest name in default scheme
    my $name = $red_like->closest_name('HTML');      # closest HTML constant
    ($name, $distance) = $color->closest_name( from => 'Pantone', all => 1 );

  distance
distance returns a numeric value, the Euclidean distance between two colors in some color space, which works even in cylindrical spaces. It accepts four named arguments: to, range, only and in. Only the "to" is required and can be provided as the only positional argument.

    my $d = $blue->distance( 'lapisblue' );                        # how close is blue to lapisblue?
    $d = $blue->distance( to => 'airyblue', only => 'b');          # do they have the same amount of blue?
    $d = $color->distance( to => $c2, only => 'hue', in => 'HSL' );# same hue?
    $d = $color->distance( to => $c2, range => 'normal' );         # distance with values in 0 .. 1 range
    $d = $color->distance( to => $c2, only => [qw/r g b b/]);      # double the weight of blue value differences

SINGLE COLOR
These methods create one GTC object with a color that is related to the current one. They can be divided into the simpler, high level convenience methods on the one side (lighten, darken, saturate, desaturate, tint, shade, tone) and the more powerful low level operations on the other (apply, set_value, add_value, mix, invert).

The signature of the high level methods is always the same. It understands 2 named arguments: "by" and "in". The first is the required one, which can be provided as a positional argument, if it is the only one. "by" needs a floating point number between 0 and 1. Usually the method produces the same color again when 0 is provided and a fixed predictable outcome when the argument is 1. The attribute in is as always the color space the method is computed in, which defaults here to OKHSL. The first 4 methods can only operate in a space of the HSL family.

  lighten
lighten increases the lightness by an absolute amount, but does not touch saturation. The result will be clamped, so lighten(1) will always return white.

    my $c = $mint->lighten( 0.1 );                      # is the same as :
    my $c = $mint->lighten( by => 0.1, in => 'OKHSL' );

  darken
darken decreases the lightness by an absolute amount, but does not touch saturation. The result will be clamped, so darken(1) will always return black.

  saturate
saturate increases the saturation by an absolute amount, but does not touch lightness. The result will be clamped, so saturate(1) will always return the purest possible color.

  desaturate
desaturate decreases the saturation by an absolute amount, but does not touch lightness. The result will be clamped, so desaturate(1) will always return a shade of grey with the same lightness as the given color.

  tint
tint mixes ("mix") a color with white by the given percentage (0.2 = 20% white, 80% given color). That lightens and desaturates at once. The result of tint(1) will always be white.

  tone
tone mixes ("mix") a color with mid gray (gray50) by the given percentage (0.2 = 20% gray50, 80% given color). That darkens or lightens and desaturates at once. The result of tone(1) will always be gray50.

  shade
shade mixes ("mix") a color with black by the given percentage (0.2 = 20% black, 80% given color). That darkens and desaturates at once. The result of shade(1) will always be black.

  tone_curve
tone_curve computes a gamma correction. It has two named arguments: "gamma" and in, the first one being required and the default argument. "in" defaults here to LinearRGB.

    my $c = $blue->tone_curve( gamma => 2.2 );                          # is the same as :
    my $c = $blue->tone_curve( gamma => {r => 2.2, g =>2.2, b => 2.2}, in => 'LinearRGB' );

  set_value
set_value returns a color that differs in some chosen values from the current one. Its arguments have to be short or long axis names from one selected color space. You may additionally provide the color space in mind with the argument in if the axis names alone are too ambiguous.

    my $blue = $black->set_value( blue => 255 );                    # same as #0000ff
    my $color = $blue->set_value( saturation => 50, in => 'HSV' );  # would otherwise use OKHSL

  add_value
Works exactly as "set_value" with only one difference: the provided axis values will be added to the current ones and not exchanged.

    my $darkblue = $blue->add_value( Lightness => -25 );    # get a darker tone
    my $blue3 = $blue->add_value( l => 10, in => 'LAB' );   # lighter color according to CIELAB

  mix
mix computes a color that is a blend between two or more other colors. It has three named arguments: to, by and in. The first one ("to") is the only required one and also the default argument. "by" defaults to a 50:50 blend and "in" to OKLAB.

    $blue->mix( $silver );                                     # 50% silver, 50% blue
    $blue->mix( to => 'silver', by => .6 );                    # 60% silver, 40% blue
    $blue->mix( to => [qw/silver green/], by => [.1, .2]);     # 10% silver, 20% green, 70% blue

  invert
invert computes a color with opposite properties (values). It has two named, optional arguments: only (select axes) and in (color space name, defaults to OKHSL).

    my $still_gray = $gray->invert();                 # got same color back
    my $blue = $yellow->invert('hue');                # invert hue in 'OKHSL'
    $yellow->invert( in => 'OKHSL', only => 'hue' );  # same in long form, same result as $yellow->complement();

COLOR SETS
These methods create sets of colors which are currently just a list of GTC objects.

  complement
complement computes colors that form a circle of complementary colors. This can only work in cylindrical spaces of the HSL family. It understands five named arguments: steps (color count), tilt, "target", "skew" and in (color space name, defaults to OKHSL). With no argument given it computes THE complementary color.

    my @colors = $c->complement( 4 );                       # 'quadratic' colors
    my @colors = $c->complement( steps => 4, tilt => 1.5 ); # split-complementary colors
    my @colors = $c->complement( steps => 3, tilt => 2, target => { l => -10 } );
    my @colors = $c->complement( steps => 3, tilt => 2, target => { h => 20, s=> -5, l => -10 });

  analogous
analogous creates a list of colors where values of neighbours differ from each other the same way as the two given colors. It accepts four named arguments: to (next color), steps (max. color count, default 4), tilt and in (color space name, defaults to OKHSL). Only "to" is required and also the default argument.

    my @colors = $darkblue->analogous( to => $midblue, steps => 5);     # 5 shades of blue
    @colors = $c->analogous( to => [14,10,222], steps => 3, tilt => 0.2, in => 'RGB' );

  gradient
gradient creates a list of colors that are a gradual blend between two or more given colors. It accepts four named arguments: to, steps (color count), "tilt" and in (color space name, defaults to OKLAB). Only "to" is required and also the default argument.

    my @colors = $c->gradient( to => $grey, steps => 5);       # we turn to grey
    @colors = $c1->gradient( to => [14,10,222], steps => 10, tilt => 1, in => 'HSL' );

  cluster
cluster creates a list of GTC color objects that look similar to the calling color but distinctly different. It accepts three named arguments: "radius", "minimal_distance" and in (color space name, defaults to OKLAB). "radius", "minimal_distance" are required and can be written "r" and "min_d".

    my @blues = $blue->cluster( radius => 4, minimal_distance => 0.3 ); # ball shapes cluster
    my @c = $color->cluster( r => [2,2,3], min_d => 0.4, in => 'YUV' ); # box shaped cluster

SEE ALSO

•   PDL::Transform::Color

•   PDL::Graphics::ColorSpace

•   Color::Scheme

•   Graphics::ColorUtils

•   Color::Fade

•   Graphics::Color

•   Graphics::ColorObject

•   Color::Calc

•   Convert::Color

•   Color::Similarity

ACKNOWLEDGEMENT
These people contributed by providing patches, bug reports and useful comments:

•   Petr Pisar (ppisar)

•   Slaven Rezic (srezic)

•   Gabor Szabo (szabgab)

•   Gene Boggs (GENE)

•   Stefan Reddig (sreagle)

AUTHOR
Herbert Breunung, <lichtkind@cpan.org>

COPYRIGHT
Copyright 2022-2026 Herbert Breunung.

LICENSE
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.