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 is the only required 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, 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.