The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

# NAME

Color::Model::RGB - Color model of RGB

# SYNOPSIS

``````    \$navy      = rgb(0, 0, 0.5);
\$limegreen = rgb('#32CD32');

# use Color::Model::RGB qw(:primary);
\$white   = R + G + B;       # addition (Constant O and W are also prepared)
\$yellow  = \$white - \$b;     # subtraction
\$midgray = \$while / 2;      # divide
\$hilight = \$midgray * 1.5;  # multiply
print qq(<span color="#\$hilight">see<span>);    # stringify

@rgbval = \$color->array();      # decimal
@rgb256 = \$color->array256();   # integers

# applying ...
@gradation = map { rgb('#010101') << \$_ } (0..7);
@tricolor  = ( \$c, rgb((\$c->array)[1,2,0]), rgb((\$c->array)[2,0,1]) );

# use Color::Model::RGB qw(:blender);
\$violet = blend_half(R, B);
\$pink   = blend_plus(R, \$hilight);``````

# DESCRIPTION

Color::Model::RGB is a color model of RGB implemented by 3D mathematical vector. This provides abstruct calculation for colors with overloding and methods to convert values to simply hexadecimal string designed for HTML, CSS and etc.

Color::Model::RGB is based on Math::VectorReal.

# CONSTANTS

Some primary colors below are defined as constant. To use these, import them with tag ':primary' or ':RGB'

``````    #     R G B
O = [ 0 0 0 ]
R = [ 1 0 0 ]
G = [ 0 1 0 ]
B = [ 0 0 1 ]
W = [ 1 1 1 ]``````

# CONSTRUCTORS

``````    \$col1 = Color::Model::RGB->new(0.1, 0.2, 0.3);
\$col2 = rgb(0.5,0.6,0.7);
\$col3 = rgb256(128,128,255);
\$col3 = rgbhex('0080ff');   # rgbhex('#0080ff') is also ok.
# and rgb(\$hexstr) is also ok.
\$col4 = \$col1->clone();``````

There are functions to make an object.

Method rgb(), rgb256() and rgbhex() are defalut exported functions returns new Color::Model::RGB object as new().

Method new() and rgb() require three decimal values as arguments. Values out of a range, from -1.0 to 1.0, will be set -1.0 or 1.0. If one argument is given to rgb(), it will be treated as a hexadecimal string and call reghex() internaly.

Method rgb256() requires three integer values from -255 to 255. Out of range value will be set -255 or 255.

Method rgbhex() requires a hexadecimal string like HTML format. An argument starts with '#' is also allowed.

clone() returns new copy of object.

# METHODS

r(), g(), b()

Returns decimal value of an element.

r256(), g256(), b256()

Returns integer value of an element, which is multiplyed by 255 and rounded by POSIX::ceil().

array() =item array256()

These methods return an array contains values of elements. array256() returns values multiplyed by 255 and rounded by POSIX::ceil().

Returns 6 digits hexadecimal string. If some string is given as argument, value starting with it returns.

truncate(), limit()

These methods return new clone object, values of elements of which are set in regulated range. truncate() makes a values lesser than 0 set to 0, and grater than 1 set to 1. And limit() set values from -1 to 1 similarly.

stringify( [ \$format [, \$flag2hex] ] )

This method can take 2 arguments. The first is format string for sprintf(), and the second is a boolean flag to convert to hexadecimal or not. If this flag is true, values multiplyed by 255 will be used at outputing. Default values of the format and the flag are keeped by package variable;

``````    \$Color::Model::RGB::FORMAT       = "%02x%02x%02x";
\$Color::Model::RGB::FORMAT_HEXED = 1;``````

Arguments are omitted at stringify() calling, these defalut values will be used.

Function set_format() and get_format() describing below gives a way to change these defalut values simply.

Color::Model::RGB inherits operators overloading from Math::VextorReal. These functions are so useful for mathematical calculation of colors.

Note: for avoiding error of conflcting with File Test Operation, put a constant object, R, B, W or O, in blanckets"()" or separate with space when using expression with muinus and them.

``````    \$c = -(W)       # OK
\$c = W - R      # OK
\$c = -W         # error or raises bug. ( Perl thinks as "-W \$_" )
\$c = W-R        # error too.``````
Negation (unary minus)
``    \$c = -\$x        # -object -> rgb(-r,-b,-c)``

A Color::Model::RGB object some values of which are minus is allowed for calculation. When stringifying such object, minus value will be represented as 0.

``````    \$c = R + G;     # object1 + object2 -> rgb(r1+r2, g1+g2, b1+b2)
\$c = B + 10;    # object  + scalar  -> rgb(r +x,  g +x,  b +x)``````
Subtraction (-)
``````    \$c = W - B;     # object1 - objext2 -> rgb(r1-r2, g1-g2, b1-b2)
\$c = W - 10;    # object  - scalar  -> rgb(r1-x,  g1-x,  b1-x)``````
Object scalar multiplication (*)
``````    \$c = W * 0.5    # object * scalar  -> rgb(r1*x,  g1*x,  b1*x)
# use Math::MatrixReal
\$c = \$col * \$m  # Color::Model::RGB * Math::MatrixReal``````

Color::Model::RGB multiplication by a object is allowed by Math::MatrixReal instance. This function may be good to calculate hue rotation of a color.

``````    # hue rotation sample
\$r = 2 * (atan2(1,1)*4) / 10; # for 2pi/10 radian
(\$sin,\$cos) = (sin(\$r), cos(\$r));
\$p  = (1/3) * (1-\$cos);
\$q  = sqrt(1/3) * \$sin; # (1/3,1/3,1/3) is norm of W

\$matrix = Math::MatrixReal->new_from_rows([
[ \$p+\$cos, \$p-\$q,   \$p+\$q,  ],
[ \$p+\$q,   \$p+\$cos, \$p-\$q,  ],
[ \$p-\$q,   \$p+\$q,   \$p+\$cos,],
]);

\$rgb = R;
foreach ( 1..10 ){
print qq(<span style="color:#\$rgb">#\$rgb</span><br>\n);
\$rgb *= \$matrix;
}``````
Object scalar division (/)
``````    \$c = W / 3      # object  / scalar  -> rgb(r1/x,  g1/x,  b1/x)
# object1 / object2 is not allowed (croaking)``````
Cross and dot products (x and .)

Calculation corss and dot product are seldom used at color manipulation. These may be used for hue rotation, too.

``````    # hue rotation sample 2
\$r = 2 * (atan2(1,1)*4) / 10; # for 2pi/10 radian
\$n = W->norm;
\$rgb = R;
foreach ( 1..10 ){
print qq(<span style="color:#\$rgb">#\$rgb</span><br>\n);
\$p = \$n * (\$n . \$rgb);
\$rgb = \$p + (\$rgb - \$p)*cos(\$r) - (\$rgb x \$n)*sin(\$r);
}``````
Bitwise operations

There are bitwise operations in Color::Model::RGB such as '<<', '>>','&', '|', '^' and '~'.

``````    \$col1 = rgbhex('010101');
\$col2 = \$col1 << 7;     # Bit shift left,  becomes 808080
\$col3 = \$col2 >> 1;     # Bit shift right, becomes 404040

\$col4 = \$col2 | \$col3;  # Object-object bit OR,  becomes c0c0c0
\$col5 = \$col2 | 0x66;   # Object-scalar bit OR,  becomes e6e6e6

\$col6 = \$col4 & \$col5   # Object-object bit AND, becomes c0c0c0
\$col7 = \$col4 & 0x80    # Object-scalar bit AND, becomes 808080

\$col8 = \$col6 ^ \$col7   # Object-object bit XOR, becomes 404040
\$col9 = \$col6 ^ 0xff;   # Object-scalar bit XOR, becomes 3f3f3f

\$col10 = ~\$col8;        # Bit Negate, becomes bfbfbf``````

In bitwise operation, each element values of Color::Model::RGB are internaly conveted to integers from 0 to 255 and than caluculated individually, and converted to decimal again.

Package parameter, \$Color::Model::RGB::BIT_SHIFT_RIGID, changes bit shift operation's result. If this is true value, caluculated value will be ANDed with 0xff. If it is false, valuse over 0xff will be set to 0xff(255). Default is false(0).

``````    \$Color::Model::RGB::BIT_SHIFT_RIGID = 1;
\$col = rgbhex('010101')<<8;     # becomes 000000
\$Color::Model::RGB::BIT_SHIFT_RIGID = 0;
\$col = rgbhex('010101')<<8;     # becomes ffffff``````

# EXPORTING FUNCTION

There are few froups for exporting.

Defalut exporting functions are rgb, rgb256 and rgbhex.

Primary colors, R (R:255,G:0,B:0), G (R:0,G:255,B:0), B (R:0,G:0,B:255), O (R:0,G:0,B:0) and W (R:255,G:255,B:255), will be exported with tag ':primary' or ':RGB'.

Functions changes defalut about stringifying, set_format and get_format, will be exported with tag ':format'.

And color blending functions, blend_alpha, blend_half, blend_plus and blend_minus, will be exported with tag ':blender'.

## CHANGING STRINGIFYING DEFALUT

set_format( \$format [, \$flag2hex] )
get_format()

Set and get defalut values of stringifying. See method stringify() descriped above.

## BLENDING FUNCTIONS

Color::Model::RGB has several blending functions which make a new object from two objects.

``````    \$blend_alpha = blend_alpha(\$col1,0.3,\$col2,0.7); # any transparency rate
\$blend_half  = blend_half(\$col1,\$col2);          # 50%:50%
\$blend_plus  = blend_plus(\$col1,\$col2);          # \$col1 + \$col2
\$blend_minus = blend_plus(\$col1,\$col2);          # \$col1 - \$col2``````

# BUGS

Please report any bugs or feature requests to `bug-color-model-rgb at rt.cpan.org`, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Color-Model-RGB. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

# SEE ASLO

Math::VectorReal by Anthony Thyssen.

# AUTHOR

T.Onodera, `<ong at garakuta.net>`