.\" Automatically generated by Pod::Man 4.11 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "ColorObject 3pm" .TH ColorObject 3pm "2020-05-22" "perl v5.30.2" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Graphics::ColorObject \- convert between color spaces .SH "SYNOPSIS" .IX Header "SYNOPSIS" use Graphics::ColorObject; .PP .Vb 3 \& # rgb to hsv \& $color = Graphics::ColorObject\->new_RGB([$r, $g, $b]); \& ($h, $s, $v) = @{ $color\->as_HSV() }; \& \& # one rgb space to another (NTSC to PAL) \& $color = Graphics::ColorObject\->new_RGB([$r, $g, $b], space=>\*(AqNTSC\*(Aq); \& ($r, $g, $b) = @{ $color\->as_RGB(space=>\*(AqPAL\*(Aq) }; .Ve .SH "ABSTRACT" .IX Header "ABSTRACT" Use this module to convert between all the common color spaces. As a pure Perl module, it is not very fast, and so it you want to convert entire images quickly, this is probably not what you want. The emphasis is on completeness and accurate conversion. .PP Supported color spaces are: \s-1RGB\s0 (including sRGB, Apple, Adobe, \s-1CIE\s0 Rec 601, \s-1CIE\s0 Rec 709, \s-1CIE ITU,\s0 and about a dozen other \s-1RGB\s0 spaces), \s-1CMY, CMYK, HSL, HSV, XYZ,\s0 xyY, Lab, LCHab, Luv, LCHuv, YPbPr, YCbCr, \s-1YUV, YIQ,\s0 PhotoYCC. .PP Conversion between different \s-1RGB\s0 working spaces, and between different white-points, is fully supported. .SH "DESCRIPTION" .IX Header "DESCRIPTION" For any supported color space \s-1XXX,\s0 there is one constructor new_XXX that creates a color using data in that color space, and one method as_XXX that returns the current color as expressed in that color space. For example, for \s-1RGB\s0 there is new_RGB and as_RGB. The color data is always passed as an array reference to a three-element array (four-element in the case of \s-1CMYK\s0). Thus, to convert from \s-1RGB\s0 to \s-1HSL,\s0 you can use: .PP .Vb 2 \& $color = Graphics::ColorObject\->new_RGB([$r, $g, $b]); \& ($h, $s, $l) = @{ $color\->as_HSL() }; .Ve .PP The constructor can always take a hash of optional arguments in addition to the color value, namely the working \s-1RGB\s0 space and the white point. For example: .PP .Vb 1 \& $color = Graphics::ColorObject\->new_RGB([$r, $g, $b], space=>\*(AqAdobe\*(Aq, white_point=>\*(AqD65\*(Aq); .Ve .PP For a list of all supported color spaces, call Graphics::ColorObject\->\fBlist_colorspaces()\fR. For a list of all \s-1RGB\s0 working spaces and of all white points that this module supports, call Graphics::ColorObject\->\fBlist_rgb_spaces()\fR and Graphics::ColorObject\->\fBlist_white_points()\fR. .PP If not specified, the working \s-1RGB\s0 space will be sRGB. Many non-RGB conversions also rely on an implicit \s-1RGB\s0 space, and passing an \s-1RGB\s0 space as an option (either to the constructor or later) will have an effect on the values. .SH "VARIOUS NOTES AND GOTCHAS" .IX Header "VARIOUS NOTES AND GOTCHAS" Most conversions will return out-of-gamut values if necessary, because that way they are lossless and can be chained in calculations, or reversed to produce the original values. Many conversion methods will take an optional boolean \*(L"clip\*(R" parameter to restrict the returned values to be within gamut: .PP .Vb 1 \& ($r, $g, $b) = @{ $color\->as_RGB(space=>\*(AqsRGB\*(Aq, clip=>1) }; .Ve .PP Currently clipping is supported in \s-1RGB,\s0 RGB-derived (\s-1HSL, CMY\s0) and chroma-luma separated (\s-1YUV,\s0 etc) spaces, but not in XYZ-derived spaces. The only way to check whether a value is within gamut is to convert it with and without the clip option and compare the two results. An \s-1RGB\s0 value is within gamut simply if R, G and B are between 0 and 1, but other spaces can be much harder to check. .PP \&\s-1RGB\s0 values are non-linear (gamma-adjusted) floating-point values scaled in the range from 0 to 1. If you want integer values in the range 0..255, use the new_RGB255/as_RGB255 functions instead. If you want linear \s-1RGB\s0 (not gamma-adjusted) use RGB_to_linear_RGB([$r, \f(CW$g\fR, \f(CW$b\fR]). .PP Functions that use an angle value always express it in degrees from 0 to 360. That includes the hue H in \s-1HSL, HSV,\s0 LCHab and LCHuv. Use rad2deg and deg2rad from Math::Trig to convert to/from degrees if necessary. .PP There is some confusion in the naming of \s-1YUV\s0 and related (Y\-something-something) colorspaces. Most of the time when \*(L"\s-1YUV\*(R"\s0 or \*(L"\s-1YCC\*(R"\s0 is used in software, for example in \s-1JPEG\s0 and \s-1MPEG2,\s0 that is actually YCbCr, a chroma-luma separated space with integer values of Y in the range [16..235], Cb and Cr in [16..240]. \s-1JPEG\s0 uses a modified YCbCr with values in [0..255] (which is not implemented in this module). As used here, \s-1YUV\s0 is a floating-point representation of the analog signal in \s-1PAL TV, YIQ\s0 is the same for \s-1NTSC TV,\s0 YPbPr is component analog video, and PhotoYCC or \s-1YCC\s0 is the Kodak PhotoCD standard. .PP The \fBset_white_point()\fR function can take arbitrary temperatures as well as the predefined standard illuminants. The valid range of temperatures is from 4000K to 25000K. .SH "RECOMMENDATIONS" .IX Header "RECOMMENDATIONS" Aside from converting from one space to another, what colorspace is the best one to use for a particular task? This section attempts to answer that question. .PP For \*(L"generic\*(R" \s-1RGB\s0 values, use sRGB (which is the default). .PP For 2D effects filters, use Lab (or LCHab). .PP For adjustment of brightness, saturation and hue, use LCHab or LSHab. .PP For compression, use YCbCr, or use YPbPr and convert to integer values in a way that makes sense in your application. .PP For representing data as colors, use Lab (straight lines between points in Lab are more-or-less uniform gradients, unlike straight lines in \s-1RGB,\s0 for example). .SH "UPGRADING FROM 0.3a2 AND OLDER VERSIONS" .IX Header "UPGRADING FROM 0.3a2 AND OLDER VERSIONS" Version 0.4 and later are a complete rewrite from the previous major version, 0.3a2. The \s-1API\s0 is completely changed. The old \s-1API\s0 should be emulated exactly in all cases. Please test any code that uses this module when upgrading. If you encounter any strange behavior, please downgrade to 0.3a2 and email me a bug report. Additionally, the exact values returned by some functions may be slightly different, this is not a bug \- the new values are (more) correct. .SH "METHODS" .IX Header "METHODS" .ie n .SS "$color = Graphics::ColorObject\->new_XYZ([$X, $Y, $Z])" .el .SS "\f(CW$color\fP = Graphics::ColorObject\->new_XYZ([$X, \f(CW$Y\fP, \f(CW$Z\fP])" .IX Subsection "$color = Graphics::ColorObject->new_XYZ([$X, $Y, $Z])" .ie n .SS "$color = Graphics::ColorObject\->new_xyY([$x, $y, $Y])" .el .SS "\f(CW$color\fP = Graphics::ColorObject\->new_xyY([$x, \f(CW$y\fP, \f(CW$Y\fP])" .IX Subsection "$color = Graphics::ColorObject->new_xyY([$x, $y, $Y])" .ie n .SS "$color = Graphics::ColorObject\->new_RGB([$R, $G, $B])" .el .SS "\f(CW$color\fP = Graphics::ColorObject\->new_RGB([$R, \f(CW$G\fP, \f(CW$B\fP])" .IX Subsection "$color = Graphics::ColorObject->new_RGB([$R, $G, $B])" .ie n .SS "$color = Graphics::ColorObject\->new_RGB255([$R, $G, $B])" .el .SS "\f(CW$color\fP = Graphics::ColorObject\->new_RGB255([$R, \f(CW$G\fP, \f(CW$B\fP])" .IX Subsection "$color = Graphics::ColorObject->new_RGB255([$R, $G, $B])" .ie n .SS "$color = Graphics::ColorObject\->new_RGBhex($rgbhex)" .el .SS "\f(CW$color\fP = Graphics::ColorObject\->new_RGBhex($rgbhex)" .IX Subsection "$color = Graphics::ColorObject->new_RGBhex($rgbhex)" .ie n .SS "$color = Graphics::ColorObject\->new_Lab([$L, $a, $b])" .el .SS "\f(CW$color\fP = Graphics::ColorObject\->new_Lab([$L, \f(CW$a\fP, \f(CW$b\fP])" .IX Subsection "$color = Graphics::ColorObject->new_Lab([$L, $a, $b])" .ie n .SS "$color = Graphics::ColorObject\->new_LCHab([$L, $C, $H])" .el .SS "\f(CW$color\fP = Graphics::ColorObject\->new_LCHab([$L, \f(CW$C\fP, \f(CW$H\fP])" .IX Subsection "$color = Graphics::ColorObject->new_LCHab([$L, $C, $H])" .ie n .SS "$color = Graphics::ColorObject\->new_Luv([$L, $u, $v])" .el .SS "\f(CW$color\fP = Graphics::ColorObject\->new_Luv([$L, \f(CW$u\fP, \f(CW$v\fP])" .IX Subsection "$color = Graphics::ColorObject->new_Luv([$L, $u, $v])" .ie n .SS "$color = Graphics::ColorObject\->new_LCHuv([$L, $C, $H])" .el .SS "\f(CW$color\fP = Graphics::ColorObject\->new_LCHuv([$L, \f(CW$C\fP, \f(CW$H\fP])" .IX Subsection "$color = Graphics::ColorObject->new_LCHuv([$L, $C, $H])" .ie n .SS "$color = Graphics::ColorObject\->new_HSL([$H, $S, $L])" .el .SS "\f(CW$color\fP = Graphics::ColorObject\->new_HSL([$H, \f(CW$S\fP, \f(CW$L\fP])" .IX Subsection "$color = Graphics::ColorObject->new_HSL([$H, $S, $L])" .ie n .SS "$color = Graphics::ColorObject\->new_HSV([$H, $S, $V])" .el .SS "\f(CW$color\fP = Graphics::ColorObject\->new_HSV([$H, \f(CW$S\fP, \f(CW$V\fP])" .IX Subsection "$color = Graphics::ColorObject->new_HSV([$H, $S, $V])" .ie n .SS "$color = Graphics::ColorObject\->new_CMY([$C, $M, $Y])" .el .SS "\f(CW$color\fP = Graphics::ColorObject\->new_CMY([$C, \f(CW$M\fP, \f(CW$Y\fP])" .IX Subsection "$color = Graphics::ColorObject->new_CMY([$C, $M, $Y])" .ie n .SS "$color = Graphics::ColorObject\->new_CMYK([$C, $M, $Y])" .el .SS "\f(CW$color\fP = Graphics::ColorObject\->new_CMYK([$C, \f(CW$M\fP, \f(CW$Y\fP])" .IX Subsection "$color = Graphics::ColorObject->new_CMYK([$C, $M, $Y])" .ie n .SS "$color = Graphics::ColorObject\->new_YPbPr([$Y, $Pb, $Pr])" .el .SS "\f(CW$color\fP = Graphics::ColorObject\->new_YPbPr([$Y, \f(CW$Pb\fP, \f(CW$Pr\fP])" .IX Subsection "$color = Graphics::ColorObject->new_YPbPr([$Y, $Pb, $Pr])" .ie n .SS "$color = Graphics::ColorObject\->new_YCbCr([$Y, $Cb, $Cr])" .el .SS "\f(CW$color\fP = Graphics::ColorObject\->new_YCbCr([$Y, \f(CW$Cb\fP, \f(CW$Cr\fP])" .IX Subsection "$color = Graphics::ColorObject->new_YCbCr([$Y, $Cb, $Cr])" .ie n .SS "$color = Graphics::ColorObject\->new_YUV([$Y, $Cb, $Cr])" .el .SS "\f(CW$color\fP = Graphics::ColorObject\->new_YUV([$Y, \f(CW$Cb\fP, \f(CW$Cr\fP])" .IX Subsection "$color = Graphics::ColorObject->new_YUV([$Y, $Cb, $Cr])" .ie n .SS "$color = Graphics::ColorObject\->new_YIQ([$Y, $I, $Q])" .el .SS "\f(CW$color\fP = Graphics::ColorObject\->new_YIQ([$Y, \f(CW$I\fP, \f(CW$Q\fP])" .IX Subsection "$color = Graphics::ColorObject->new_YIQ([$Y, $I, $Q])" .ie n .SS "$color = Graphics::ColorObject\->new_PhotoYCC([$Y, $C1, $C2])" .el .SS "\f(CW$color\fP = Graphics::ColorObject\->new_PhotoYCC([$Y, \f(CW$C1\fP, \f(CW$C2\fP])" .IX Subsection "$color = Graphics::ColorObject->new_PhotoYCC([$Y, $C1, $C2])" .ie n .SS "($X, $Y, $Z) = @{ $color\->\fBas_XYZ()\fP }" .el .SS "($X, \f(CW$Y\fP, \f(CW$Z\fP) = @{ \f(CW$color\fP\->\fBas_XYZ()\fP }" .IX Subsection "($X, $Y, $Z) = @{ $color->as_XYZ() }" .ie n .SS "($R, $G, $B) = @{ $color\->\fBas_RGB()\fP }" .el .SS "($R, \f(CW$G\fP, \f(CW$B\fP) = @{ \f(CW$color\fP\->\fBas_RGB()\fP }" .IX Subsection "($R, $G, $B) = @{ $color->as_RGB() }" .ie n .SS "($R, $G, $B) = @{ $color\->\fBas_RGB255()\fP }" .el .SS "($R, \f(CW$G\fP, \f(CW$B\fP) = @{ \f(CW$color\fP\->\fBas_RGB255()\fP }" .IX Subsection "($R, $G, $B) = @{ $color->as_RGB255() }" .ie n .SS "$hex = $color\->\fBas_RGBhex()\fP" .el .SS "\f(CW$hex\fP = \f(CW$color\fP\->\fBas_RGBhex()\fP" .IX Subsection "$hex = $color->as_RGBhex()" .ie n .SS "($x, $y, $Y) = @{ $color\->\fBas_xyY()\fP }" .el .SS "($x, \f(CW$y\fP, \f(CW$Y\fP) = @{ \f(CW$color\fP\->\fBas_xyY()\fP }" .IX Subsection "($x, $y, $Y) = @{ $color->as_xyY() }" .ie n .SS "($L, $a, $b) = @{ $color\->\fBas_Lab()\fP }" .el .SS "($L, \f(CW$a\fP, \f(CW$b\fP) = @{ \f(CW$color\fP\->\fBas_Lab()\fP }" .IX Subsection "($L, $a, $b) = @{ $color->as_Lab() }" .ie n .SS "($L, $C, $H) = @{ $color\->\fBas_LCHab()\fP }" .el .SS "($L, \f(CW$C\fP, \f(CW$H\fP) = @{ \f(CW$color\fP\->\fBas_LCHab()\fP }" .IX Subsection "($L, $C, $H) = @{ $color->as_LCHab() }" .ie n .SS "($L, $u, $v) = @{ $color\->\fBas_Luv()\fP }" .el .SS "($L, \f(CW$u\fP, \f(CW$v\fP) = @{ \f(CW$color\fP\->\fBas_Luv()\fP }" .IX Subsection "($L, $u, $v) = @{ $color->as_Luv() }" .ie n .SS "($L, $C, $H) = @{ $color\->\fBas_LCHuv()\fP }" .el .SS "($L, \f(CW$C\fP, \f(CW$H\fP) = @{ \f(CW$color\fP\->\fBas_LCHuv()\fP }" .IX Subsection "($L, $C, $H) = @{ $color->as_LCHuv() }" .ie n .SS "($H, $S, $L) = @{ $color\->\fBas_HSL()\fP }" .el .SS "($H, \f(CW$S\fP, \f(CW$L\fP) = @{ \f(CW$color\fP\->\fBas_HSL()\fP }" .IX Subsection "($H, $S, $L) = @{ $color->as_HSL() }" .ie n .SS "($H, $S, $V) = @{ $color\->\fBas_HSV()\fP }" .el .SS "($H, \f(CW$S\fP, \f(CW$V\fP) = @{ \f(CW$color\fP\->\fBas_HSV()\fP }" .IX Subsection "($H, $S, $V) = @{ $color->as_HSV() }" .ie n .SS "($C, $M, $Y) = @{ $color\->\fBas_CMY()\fP }" .el .SS "($C, \f(CW$M\fP, \f(CW$Y\fP) = @{ \f(CW$color\fP\->\fBas_CMY()\fP }" .IX Subsection "($C, $M, $Y) = @{ $color->as_CMY() }" .ie n .SS "($C, $M, $Y, $K) = @{ $color\->\fBas_CMYK()\fP }" .el .SS "($C, \f(CW$M\fP, \f(CW$Y\fP, \f(CW$K\fP) = @{ \f(CW$color\fP\->\fBas_CMYK()\fP }" .IX Subsection "($C, $M, $Y, $K) = @{ $color->as_CMYK() }" .ie n .SS "($Y, $Pb, $Pr) = @{ $color\->\fBas_YPbPr()\fP }" .el .SS "($Y, \f(CW$Pb\fP, \f(CW$Pr\fP) = @{ \f(CW$color\fP\->\fBas_YPbPr()\fP }" .IX Subsection "($Y, $Pb, $Pr) = @{ $color->as_YPbPr() }" .ie n .SS "($Y, $Cb, $Cr) = @{ $color\->\fBas_YCbCr()\fP }" .el .SS "($Y, \f(CW$Cb\fP, \f(CW$Cr\fP) = @{ \f(CW$color\fP\->\fBas_YCbCr()\fP }" .IX Subsection "($Y, $Cb, $Cr) = @{ $color->as_YCbCr() }" .ie n .SS "($Y, $U, $V) = @{ $color\->\fBas_YUV()\fP }" .el .SS "($Y, \f(CW$U\fP, \f(CW$V\fP) = @{ \f(CW$color\fP\->\fBas_YUV()\fP }" .IX Subsection "($Y, $U, $V) = @{ $color->as_YUV() }" .ie n .SS "($Y, $I, $Q) = @{ $color\->\fBas_YIQ()\fP }" .el .SS "($Y, \f(CW$I\fP, \f(CW$Q\fP) = @{ \f(CW$color\fP\->\fBas_YIQ()\fP }" .IX Subsection "($Y, $I, $Q) = @{ $color->as_YIQ() }" .ie n .SS "($Y, $C1, $C2) = @{ $color\->\fBas_PhotoYCC()\fP }" .el .SS "($Y, \f(CW$C1\fP, \f(CW$C2\fP) = @{ \f(CW$color\fP\->\fBas_PhotoYCC()\fP }" .IX Subsection "($Y, $C1, $C2) = @{ $color->as_PhotoYCC() }" .ie n .SS "$white_point = $color\->\fBget_white_point()\fP Returns the name of the current white point. Value is one of the entries returned from list_white_points, such as ""D65"", or a color temperature." .el .SS "\f(CW$white_point\fP = \f(CW$color\fP\->\fBget_white_point()\fP Returns the name of the current white point. Value is one of the entries returned from list_white_points, such as ``D65'', or a color temperature." .IX Subsection "$white_point = $color->get_white_point() Returns the name of the current white point. Value is one of the entries returned from list_white_points, such as D65, or a color temperature." .ie n .SS "$color\->set_white_point(""D65"") Sets the current white point by name. Argument is one of the entries returned from list_white_points, or a temperature value like ""6800K"". This changes the current color slightly since white-point adaptation is not completely reversible. This does not affect the current \s-1RGB\s0 space, thus it is possible to use \s-1RGB\s0 spaces at whitepoints other than those they were defined at." .el .SS "\f(CW$color\fP\->set_white_point(``D65'') Sets the current white point by name. Argument is one of the entries returned from list_white_points, or a temperature value like ``6800K''. This changes the current color slightly since white-point adaptation is not completely reversible. This does not affect the current \s-1RGB\s0 space, thus it is possible to use \s-1RGB\s0 spaces at whitepoints other than those they were defined at." .IX Subsection "$color->set_white_point(D65) Sets the current white point by name. Argument is one of the entries returned from list_white_points, or a temperature value like 6800K. This changes the current color slightly since white-point adaptation is not completely reversible. This does not affect the current RGB space, thus it is possible to use RGB spaces at whitepoints other than those they were defined at." .ie n .SS "$rgb_space = $color\->\fBget_rgb_space()\fP Returns the name of the current \s-1RGB\s0 color space. Value is one of the entries returned from list_rgb_spaces, such as ""\s-1NTSC"".\s0" .el .SS "\f(CW$rgb_space\fP = \f(CW$color\fP\->\fBget_rgb_space()\fP Returns the name of the current \s-1RGB\s0 color space. Value is one of the entries returned from list_rgb_spaces, such as ``\s-1NTSC''.\s0" .IX Subsection "$rgb_space = $color->get_rgb_space() Returns the name of the current RGB color space. Value is one of the entries returned from list_rgb_spaces, such as NTSC." .ie n .SS "$color\->set_rgb_space(""\s-1NTSC""\s0) Sets the current \s-1RGB\s0 color space by name. Argument is one of the entries returned from list_rgb_spaces. This may change the current color if the old and new spaces have different white points." .el .SS "\f(CW$color\fP\->set_rgb_space(``\s-1NTSC''\s0) Sets the current \s-1RGB\s0 color space by name. Argument is one of the entries returned from list_rgb_spaces. This may change the current color if the old and new spaces have different white points." .IX Subsection "$color->set_rgb_space(NTSC) Sets the current RGB color space by name. Argument is one of the entries returned from list_rgb_spaces. This may change the current color if the old and new spaces have different white points." .ie n .SS "$color2 = $color\->\fBcopy()\fP Creates an exact duplicate of the current color." .el .SS "\f(CW$color2\fP = \f(CW$color\fP\->\fBcopy()\fP Creates an exact duplicate of the current color." .IX Subsection "$color2 = $color->copy() Creates an exact duplicate of the current color." .SS "if ($color\->equals($color2)) { ... } Checks if another color is the same as this one. Optionally takes an accuracy parameter which is the distance between the two colors as measured by the city-block metric in \s-1XYZ\s0 space (default accuracy is 0.01%)." .IX Subsection "if ($color->equals($color2)) { ... } Checks if another color is the same as this one. Optionally takes an accuracy parameter which is the distance between the two colors as measured by the city-block metric in XYZ space (default accuracy is 0.01%)." .ie n .SS "$d = $color\->difference($color2) Calculates the difference between this color and another one. The difference measure is (approximately) perceptually uniform." .el .SS "\f(CW$d\fP = \f(CW$color\fP\->difference($color2) Calculates the difference between this color and another one. The difference measure is (approximately) perceptually uniform." .IX Subsection "$d = $color->difference($color2) Calculates the difference between this color and another one. The difference measure is (approximately) perceptually uniform." .ie n .SS "@colorspaces = &Graphics::ColorObject\->\fBlist_colorspaces()\fP Returns a list of all supported colorspaces." .el .SS "\f(CW@colorspaces\fP = &Graphics::ColorObject\->\fBlist_colorspaces()\fP Returns a list of all supported colorspaces." .IX Subsection "@colorspaces = &Graphics::ColorObject->list_colorspaces() Returns a list of all supported colorspaces." .ie n .SS "@rgb_spaces = &Graphics::ColorObject\->\fBlist_rgb_spaces()\fP Returns a list of all supported \s-1RGB\s0 spaces. Some items are aliases, so the same space may be listed more than once under different names." .el .SS "\f(CW@rgb_spaces\fP = &Graphics::ColorObject\->\fBlist_rgb_spaces()\fP Returns a list of all supported \s-1RGB\s0 spaces. Some items are aliases, so the same space may be listed more than once under different names." .IX Subsection "@rgb_spaces = &Graphics::ColorObject->list_rgb_spaces() Returns a list of all supported RGB spaces. Some items are aliases, so the same space may be listed more than once under different names." .ie n .SS "@white_points = &Graphics::ColorObject\->\fBlist_white_points()\fP Returns a list of all supported white points." .el .SS "\f(CW@white_points\fP = &Graphics::ColorObject\->\fBlist_white_points()\fP Returns a list of all supported white points." .IX Subsection "@white_points = &Graphics::ColorObject->list_white_points() Returns a list of all supported white points." .SS "\s-1EXPORT\s0" .IX Subsection "EXPORT" None by default. The 'all' tag causes the non-object-oriented interface to be exported, and you get all the XXX_to_YYY functions, for example RGB_to_XYZ. Please note that some of these functions need extra arguments in addition to the color value to be converted. .SH "BUGS" .IX Header "BUGS" Backwards compatibility with versions before 0.4 is not very well tested. .PP This module will produce results that are, in some cases, different from other software. Most of the time that is not a bug in this module, but rather a case where the other software uses an approximate (trading accuracy for speed) algorithm. That is particularly true for \s-1YUV\s0 and related conversions which are often implemented using integer-math approximations. As far as possible, this module produces results which are exact according to the definitions in the relevant \s-1CIE/ITU\s0 or other standards. .PP Some color transformations are not exactly reversible. In particular, conversions between different white points are almost but not exactly reversible. This is not a bug. .PP There is no way to choose any other color-adaptation algorithm than the Bradford algorithm. That is probably ok since the Bradford algorithm is better than other algorithms (such as Von Kries or simple scaling). .PP There is no way to choose a \s-1RGB\s0 space other than the built-in ones. .PP Support for \s-1CMYK\s0 is very basic, it relies on assumptions that completely do not work in the physical world of subtractive pigment mixtures. If you tried to convert an image to \s-1CMYK\s0 directly for printing using these functions, the results will not be very good, to say the least. .SH "TODO" .IX Header "TODO" Add clipping to gamut for every color space. .PP Choose between several clipping algorithms (nearest, luminance-preserving, hue-preserving). .PP Add a simpler way to check whether something is within gamut. .PP Add user-defined \s-1RGB\s0 spaces. .PP Calculate \s-1RGB\s0 matrices from chromaticity coordinates. .PP Only load non-RGB matrices once at startup. .PP Add colorspaces: uvw, \s-1YOZ, RYB,\s0 others? .PP Add \s-1RGB\s0 spaces: \s-1ROMM,\s0 others? .PP Convert arrays of colors efficiently (maybe someday in C). .SH "SEE ALSO" .IX Header "SEE ALSO" The Color \s-1FAQ\s0 by Charles Poynton is one of the definitive references on the subject: http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.txt .PP Bruce Lindbloom's web site contains a tremendous amount of information on color: http://www.brucelindbloom.com/index.html?Math.html .SH "AUTHOR" .IX Header "AUTHOR" Alex Izvorski, .PP Alfred Reibenschuh was the original author for versions up to 0.3a2. .PP Many thanks to: .PP Alfred Reibenschuh for the previous versions of Graphics::ColorObject, and for the \s-1HSL/HSV/CMYK\s0 code. .PP Bruce Lindbloom for providing a wealth of information on color space conversion and color adaptation algorithms, and for the precalculated \s-1RGB\s0 conversion matrices. .PP Charles Poynton for the Color \s-1FAQ.\s0 .PP Timo Autiokari for information on white points. .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" Copyright 2003\-2005 by Alex Izvorski .PP Portions Copyright 2001\-2003 by Alfred Reibenschuh .PP This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.