/* ********************************************************************* This source file is a part of the standard library of Scol For the latest info, see http://www.scolring.org Copyright (c) 2015 Stephane Bisaro aka Iri. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or go to http://www.gnu.org/copyleft/lesser.txt ********************************************************************* */ /* * 2d functions for Scol * See http://redmine.scolring.org/projects/tutorials/wiki/Scol_usage * for more informations */ /*! \file colors.pkg * \author Scol team * \version 0.1 * \copyright GNU Lesser General Public License 2.0 or later * \brief Scol 2d colors API * * * Important: Colors are presented as a result of mathematical calculations. * Conversions may be inaccurate / approximate / useless. * * Dependancies : * - lib/std/stdlib.pkg * * \example 2d/grayscale.pkg_ * **/ /* PRIVATE FUNCTIONS */ /* Returns the complementary color from (red, green, blue) * in : red -> I : 0 -> 255 * green -> I : 0 -> 255 * blue -> I : 0 -> 255 * out : r' -> I : 0 -> 255 * out : g' -> I : 0 -> 255 * out : b' -> I : 0 -> 255 */ fun l2d_colorsComplementaryFromRGB (r, g, b)= [255-r 255-g 255-b];; /* Returns the complementary color from (hue, saturation, value) * in : hue -> F : 0.0 -> 360.0 * saturation -> F : 0.0 -> 1.0 * value -> F : 0.0 -> 1.0 * out : h' -> F : 0.0 -> 360.0 * out : s' -> F : 0.0 -> 1.0 * out : v' -> F : 0.0 -> 1.0 */ fun l2d_colorsComplementaryFromHSV (H, S, V)= let [nil nil nil] -> [h s v] in ( if H >=. 180.0 then set h = H-.180.0 else set h = H+.180.0; set v = (V*.(S-.1.0))+.1.0; if v == 0.0 then set s = 0.0 else set s = (V*.S)/.v; // v et s apporte une correction qui n'est pas jugé utile par tous. Actu, je ne l'utilise pas. [h S V] );; /* let if H >=. 180.0 then H-.180.0 else H+.180.0 -> h in [h (V*.S)/.((V*.(S-.1.0))+.1.0) V*.(S-.1.0)+.1.0];;*/ //[h S V];; /* Returns the natural color system (ncs) code, if it exists, from a RGB 24-bits color * in : red -> I : 0 -> 255 * green -> I : 0 -> 255 * blue -> I : 0 -> 255 * out : ncs -> S : the color string or "ERROR" * * note : Don't use this, it works incorrectly */ fun l2d_colors_rgb2ncs (red, green, blue)= // ncs : natural color system let [nil nil nil] -> [r g b] in let [nil nil nil] -> [m iw y] in let [nil nil nil nil nil] -> [c1 c2 n c s] in ( set r = (itof red)/.255.0; set g = (itof green)/.255.0; set b = (itof blue)/.255.0; set m = minf minf r g b; set iw = ftoi (m*.100.0); set y = 0.0; set r = r-.m; set g = g-.m; set b = b-.m; if (r == 0.0) && (g == 0.0) && (b == 0.0) then if iw == 0 then ( set c1 = "B"; set c2 = " "; set n = "0"; set c = "0"; ) else if iw == 100 then ( set c1 = "W"; set c2 = " "; set n = "0"; set c = "0"; ) else ( set c1 = "N"; set c2 = " "; set n = "0"; set c = "0"; ) else if (r == 0.0) && (b == 0.0) then ( set c1 = "G"; set c2 = " "; set n = "0"; set c = itoa ftoi (g*.100.0); ) else if (r == 0.0) && (g == 0.0) then ( set c1 = "B"; set c2 = " "; set n = "0"; set c = itoa ftoi (b*.100.0); ) else if (g == 0.0) && (b == 0.0) then ( set c1 = "R"; set c2 = " "; set n = "0"; set c = itoa ftoi (r*.100.0); ) else if r == g then ( set y = g; set r = 0.0; set g = 0.0; set c1 = "Y"; set c2 = " "; set n = "0"; set c = itoa ftoi (y*.100.0); ) else if r == 0.0 then ( set c1 = "G"; set c2 = "B"; set n = itoa ftoi ((b*.100.0)/.(g+.b)); set y = 0.0; nil ) else if g == 0.0 then ( set c1 = "B"; set c2 = "R"; set n = itoa ftoi ((r*.100.0)/.(r+.b)); set y = 0.0; nil ) else if (b == 0.0) && (g <. r) then ( set c1 = "R"; set c2 = "Y"; set y = g; set r = r-.g; set g = 0.0; set n = itoa ftoi ((y*.100.0)/.(r+.y)); ) else if (b == 0.0) && (r <. g) then ( set c1 = "Y"; set c2 = "G"; set y = r; set g = g-.r; set r = 0.0; set n = itoa ftoi ((g*.100.0)/.(g+.y)); ) else ( set c1 = "ERROR"; set c2 = ""; set n = ""; set c = ""; set s = ""; ); if c == nil then set c = itoa ftoi ((maxf maxf maxf r g b y)*.100.0); if s == nil then set s = itoa ftoi (100.0-.(atof c)-.(itof iw)); if (atoi c) < 10 then set c = strcat "0" c; if (atoi s) < 10 then set s = strcat "0" s; sprintf "%s.%s-%s.%s.%s" [s c c2 n c1]; );; /* Converts a RGB component from integer to hexadecimal * in : red -> I : 0 -> 255 * green -> I : 0 -> 255 * blue -> I : 0 -> 255 * out : red -> S : in hex * out : green -> S : in hex * out : blue -> S : in hex */ fun l2d_colors_rgb2hex (red, green, blue)= [itoh red itoh green itoh blue];; /* Converts a RGB component from hexadecimal to integer * in : red -> S : 00 -> FF * green -> S : 00 -> FF * blue -> S : 00 -> FF * out : red -> I : 0 -> 255 * green -> I : 0 -> 255 * blue -> I : 0 -> 255 */ fun l2d_colors_hex2int (red, green, blue)= [htoi red htoi green htoi blue];; /* Converts a RGB 24-bits color to its CMYK components * in : red -> I : 0 -> 255 * green -> I : 0 -> 255 * blue -> I : 0 -> 255 * out : cyan -> I : 0 -> 100 * out : magenta -> I : 0 -> 100 * out : yellow -> I : 0 -> 100 * out : key (black) -> I : 0 -> 100 */ fun l2d_colors_rgb2cmyk (red, green, blue)= let [nil nil nil] -> [r g b] in let nil -> K in let [nil nil nil] -> [Cw Mw Yw] in // C M Y from white space let [nil nil nil] -> [Cb Mb Yb] in // C M Y from black space ( set r = (itof red)/.255.0; set g = (itof green)/.255.0; set b = (itof blue)/.255.0; // calculates the same first CMY values for the two spaces set Cb = 1.0-.r; set Mb = 1.0-.g; set Yb = 1.0-.b; set K = minf minf Cb Mb Yb; // key (black) // from white space (used by GIMP or Photoshop by example) if K == 1.0 then ( set Cw = 0.0; set Mw = 0.0; set Yw = 0.0; ) else ( set Cw = (Cb-.K)/.(1.0-.K); set Mw = (Mb-.K)/.(1.0-.K); set Yw = (Yb-.K)/.(1.0-.K); ); // from black space (used by LibreOffice or MS Office by example) if K == 1.0 then ( set Cb = 0.0; set Mb = 0.0; set Yb = 0.0; ) else ( set Cb = Cb-.K; set Mb = Mb-.K; set Yb = Yb-.K; ); set K = K*.100.0; [[(ftoi Cb)*100 (ftoi Mb)*100 (ftoi Yb)*100 ftoi K] [(ftoi Cw)*100 (ftoi Mw)*100 (ftoi Yw)*100 ftoi K]] );; /* Converts a RGB 24-bits color to its CMYK components * in : cyan -> I : 0 -> 100 * : magenta -> I : 0 -> 100 * : yellow -> I : 0 -> 100 * : key (black) -> I : 0 -> 100 * : space -> I : 1 to 'white' space * out : red -> I : 0 -> 255 * out : green -> I : 0 -> 255 * out : blue -> I : 0 -> 255 */ fun l2d_colors_cmyk2rvb (cyan, magenta, yellow, key, space)= let [nil nil nil] -> [r g b] in let [nil nil nil nil] -> [c m y k] in ( set c = (itof cyan)/.100.0; set m = (itof magenta)/.100.0; set y = (itof yellow)/.100.0; set k = (itof key)/.100.0; // CMJK to CMJ space if space then // 1 : white space ( set c = (c*.(1.0-.k))+.k; set m = (m*.(1.0-.k))+.k; set y = (y*.(1.0-.k))+.k; ) else // 'black' space ( set c = c+.k; set m = m+.k; set y = y+.k; ); set r = 1.0-.c; set g = 1.0-.m; set b = 1.0-.y; [(ftoi r)*255 (ftoi g)*255 (ftoi b)*255] );; /* Return the three RGB components from a 24-bits RGB color */ fun l2d_colorsrgb2c (c) = /* c = 24 bits color */ let (c>>16) & 255 -> b in let (c>>8) & 255 -> g in let c & 255 -> r in [r g b];; /* Convert (hue, saturation, value) to (red, green, blue) * in : hue -> I : 0 -> 360 * saturation -> I : 0 -> 100 * value -> I : 0 -> 100 * out : r -> F : 0.0 -> 1.0 * out : g -> F : 0.0 -> 1.0 * out : b -> F : 0.0 -> 1.0 */ fun l2d_colors_hsv2rgb (hue, saturation, value) = let [nil nil nil] -> [h s v] in //let [nil nil nil nil] -> [C H X m] in let [nil nil nil nil nil] -> [C H l m n] in ( set h = itof hue; //set h = (itof hue)/.360.0; set s = (itof saturation)/.100.0; set v = (itof value)/.100.0; if s == 0.0 then [v v v] else ( set H = itof mod (ftoi h)/60 6; set C = (h/.60.0)-.H; set l = v*.(1.0-.s); set m = v*.(1.0-.(C*.s)); set n = v*.(1.0-.((1.0-.C)*.s)); if H == 0.0 then [v n l] else if H == 1.0 then [m v l] else if H == 2.0 then [l v n] else if H == 3.0 then [l m v] else if H == 4.0 then [n l v] else [v l m] ) );; /* Convert (red, green, blue) to (hue, saturation, value) * in : r -> I : 0 -> 255 * in : g -> I : 0 -> 255 * in : b -> I : 0 -> 255 * out : h -> F : 0.0 -> 360.0 * out : s -> F : 0.0 -> 1.0 * out : v -> F : 0.0 -> 1.0 */ fun l2d_colors_rgb2hsv (red, green, blue)= let [nil nil nil] -> [r g b] in let [nil nil nil] -> [M m C] in let [nil nil nil] -> [h s v] in ( set r = (itof red)/.255.0; set g = (itof green)/.255.0; set b = (itof blue)/.255.0; set M = maxf maxf r g b; set m = minf minf r g b; set C = M-.m; if M == m then set h = 0.0 else if M == r then let (60.0*.((g-.b)/.C))+.360.0 -> f in let modf f/.360.0 0.0 -> q in // decimal part of the division set h = q+.itof mod ftoi f 360 else if M == g then set h = (60.0*.((b-.r)/.C))+.120.0 else if M == b then set h = (60.0*.((r-.g)/.C))+.240.0; set v = M; if M == 0.0 then set s = 0.0 else set s = 1.0-.(m/.M); [h s v] );; // used by l2d_colors_hsl2rgb below fun l2d_colors_hue2rgb (m1, m2, h)= if h <. 0.0 then set h = h+.1.0; if h >. 1.0 then set h = h-.1.0; if (h*.6.0) <. 1.0 then m1+.((m2-.m1)*.h*.6.0) else if (h*.2.0) <. 1.0 then m2 else if (h*.3.0) <. 2.0 then m1+.((m2-.m1)*.((2.0/.3.0)-.h)*.6.0) else m1;; /* Converts a HSL color to a RGB color * in : hue -> I : 0..360 * : saturation -> I : 0..100 * : lightness -> I : 0..100 * out: red -> F : 0.0..1.0 * : green -> F : 0.0..1.0 * : blue -> F : 0.0..1.0 */ fun l2d_colors_hsl2rgb (hue, saturation, lightness)= let [nil nil nil] -> [h s l] in let [nil nil nil nil nil] -> [m1 m2 r g b] in ( set h = itof hue; set s = (itof saturation)/.100.0; set l = (itof lightness)/.100.0; if l <=. 0.5 then set m2 = l*.(s+.1.0) else set m2 = l+.s-.(l*.s); set m1 = (l*.2.0)-.m2; set r = l2d_colors_hue2rgb m1 m2 h+.(1.0/.3.0); set g = l2d_colors_hue2rgb m1 m2 h; set b = l2d_colors_hue2rgb m1 m2 h-.(1.0/.3.0); [r g b] );; /* Converts a RGB color to a HSL color * in : red -> I : 0..255 * : green -> I : 0..255 * : blue -> I : 0..255 * out: hue -> F : 0.0..1.0 * : saturation -> F : 0.0..1.0 * : lightness -> F : 0.0..1.0 */ fun l2d_colors_rgb2hsl (red, green, blue)= let [nil nil nil] -> [r g b] in let [nil nil nil] -> [m M C] in let [nil nil nil] -> [h s l] in ( set r = (itof red)/.255.0; set g = (itof green)/.255.0; set b = (itof blue)/.255.0; set m = minf minf r g b; set M = maxf maxf r g b; set C = M-.m; set l = (M+.m)/.2.0; if C == 0.0 then ( set h = 0.0; // convention, else undefined set s = 0.0 ) else ( if l <. 0.5 then set s = C/.(m+.M) else set s = C/.(2.0-.M-.m); let (((M-.r)/.6.0)+.(C/.2.0))/.C -> cr in let (((M-.g)/.6.0)+.(C/.2.0))/.C -> cg in let (((M-.b)/.6.0)+.(C/.2.0))/.C -> cb in if M == r then set h = cb-.cg else if M == g then set h = (1.0/.3.0)+.cr-.cb else // M == b set h = (2.0/.30.)+.cg-.cr; if h <. 0.0 then //++h // not an integer set h = h+.1.0 else if h >. 1.0 then //--h; // not an integer set h = h-.1.0; ); [h s l] );; /* Returns the 24-bits colors from its three RGB components * in : red -> I * in : green -> I * in : blue -> I * out : color -> I */ fun l2d_colorsrgb (r, g, b)= make_rgb r g b;; /* Returns the color from a standardized css name * in : name -> S : a color name * out : tuple [S S [I I I]] * : - name -> S : the same given name * : - hex -> S : the hexadecimal value * : - rgb -> [I I I] : the three rgb components in integer * or nil if the color name is not found */ fun l2d_colorscss (name)= let strextr _getpack _checkpack "lib/2d/rscs/colors_css" -> l in let switchstri l name -> r in if r == nil then nil else [name hd r [atoi hd tl r atoi hd tl tl r atoi hd tl tl tl r]];; /* Returns the gray value from a RGB color ("average method") * * Used formula is : Gray = (Red + Green + Blue) / 3 * * in : red -> I : 0..255 * : green -> I : 0..255 * : blue -> I : 0..255 * out : gray -> I : 0..255 * : gray -> I : 0..255 * : gray -> I : 0..255 */ fun l2d_colorsgrayscaleOne (r, g, b)= let (r+g+b)/3 -> a in [a a a];; /* Returns the gray value from a RGB color ("human eye correction") * * Used formula is : Gray = Red * 0.3 + Green * 0.59 + Blue * 0.11 * * in : red -> I : 0..255 * : green -> I : 0..255 * : blue -> I : 0..255 * out : gray -> I : 0..255 * : gray -> I : 0..255 * : gray -> I : 0..255 */ fun l2d_colorsgrayscaleTwoA (r, g, b)= let ftoi (((itof r)*.0.3)+.((itof g)*.0.59)+.((itof b)*.0.11)) -> a in [a a a];; /* Returns the gray value from a RGB color ("human eye correction") * * Used formula is : Gray = Red * 0.2126 + Green * 0.7152 + Blue * 0.0722 * * in : red -> I : 0..255 * : green -> I : 0..255 * : blue -> I : 0..255 * out : gray -> I : 0..255 * : gray -> I : 0..255 * : gray -> I : 0..255 */ fun l2d_colorsgrayscaleTwoB (r, g, b)= let ftoi (((itof r)*.0.2126)+.((itof g)*.0.7152)+.((itof b)*.0.0722)) -> a in [a a a];; /* Returns the gray value from a RGB color ("human eye correction") * * Used formula is : Gray = Red * 0.299 + Green * 0.587 + Blue * 0.114 * * in : red -> I : 0..255 * : green -> I : 0..255 * : blue -> I : 0..255 * out : gray -> I : 0..255 * : gray -> I : 0..255 * : gray -> I : 0..255 */ fun l2d_colorsgrayscaleTwoC (r, g, b)= let ftoi (((itof r)*.0.299)+.((itof g)*.0.587)+.((itof b)*.0.114)) -> a in [a a a];; /* Returns the gray value from a RGB color ("desaturation") * * Used formula is : Gray = (Max(Red, Green, Blue) + Min(Red, Green, Blue)) / 2 * * in : red -> I : 0..255 * : green -> I : 0..255 * : blue -> I : 0..255 * out : gray -> I : 0..255 * : gray -> I : 0..255 * : gray -> I : 0..255 */ fun l2d_colorsgrayscaleThree (r, g, b)= let [nil nil nil] -> [m M a] in ( set m = min min r g b; set M = max max r g b; set a = (M+m)/2; [a a a] );; /* Returns the gray value from a RGB color ("decomposition") * * Used formula is : Gray = Max (Red, Green, Blue) or Gray = Min (Red, Green, Blue) * * in : red -> I : 0..255 * : green -> I : 0..255 * : blue -> I : 0..255 * : flag -> I : 1 : with Maximun, 0 with Minimum * out : gray -> I : 0..255 * : gray -> I : 0..255 * : gray -> I : 0..255 */ fun l2d_colorsgrayscaleFour (r, g, b, f)= set f = std_clamp f 0 1; let if f then max max r g b else min min r g b -> a in [a a a];; /* Returns the gray value from a RGB color ("single gray channel") * * Used formula is : Gray = Red or Gray = Green or Gray = Blue * * in : red -> I : 0..255 * : green -> I : 0..255 * : blue -> I : 0..255 * : flag -> I : 0 to red, 1 to green, 2 to blue * out : gray -> I : 0..255 * : gray -> I : 0..255 * : gray -> I : 0..255 */ fun l2d_colorsgrayscaleFive (r, g, b, f)= set f = std_clamp f 0 2; let if f == 2 then b else if f then g else r -> a in [a a a];; /* Returns the gray value from a RGB color ("custom gray shaders") * * The formula depends on the given shaders number. * * in : red -> I : 0..255 * : green -> I : 0..255 * : blue -> I : 0..255 * : shaders -> I : 2..256 : 2 -> black and white, 256 -> like "average method" * out : gray -> I : 0..255 * : gray -> I : 0..255 * : gray -> I : 0..255 */ fun l2d_colorsgrayscaleSix (r, g, b, s)= set s = std_clamp s 2 256; let [nil nil nil] -> [c v a] in ( //set c = 255.0/.((itof s)-.1.0); set c = 255/(s-1); set v = (r+g+b)/3; //set a = ftoi ((((itof v)/.c)+.0.5)*.c); set a = (ftoi ((((itof v)/.(itof c))+.0.5)))*c; [a a a] );; /* PUBLIC FUNCTIONS */ /*! Convert the three RGB components to the three HSV components * * \ingroup l2d_colors * Prototype : fun [I I I] [F F F] * * \param I : the red component [0..255] * \param I : the green component [0..255] * \param I : the blue component [0..255] * \return [F F F] : the hue [0.0 .. 360.0], the saturation [0.0 .. 1.0], the value [0.0 .. 1.0] components */ fun l2d_colorsConvertRGB2HSV (iRed, iGreen, iValue)= set iRed = std_clamp iRed 0 255; set iGreen = std_clamp iGreen 0 255; set iValue = std_clamp iValue 0 255; l2d_colors_rgb2hsv iRed iGreen iValue;; /*! Convert the three HSV components to the three RGB components * * \ingroup l2d_colors * Prototype : fun [I I I] [F F F] * * \param I : the hue component [0..360] * \param I : the saturation component [0..100] * \param I : the value component [0..100] * \return [F F F] : the red [0.0 .. 1.0], the green [0.0 .. 1.0], the blue [0.0 .. 1.0] components */ fun l2d_colorsConvertHSV2RGB (iHue, iSaturation, iValue)= set iHue = std_clamp iHue 0 360; set iSaturation = std_clamp iSaturation 0 100; set iValue = std_clamp iValue 0 100; l2d_colors_hsv2rgb iHue iSaturation iValue;; /*! Convert a 24 bits color to its three RGB components * * \ingroup l2d_colors * Prototype : fun [I] [I I I] * * \param I : a 24-bits color (0..16777216) * \return [I I I] : the red [0..255], the green [0..255], the blue [0..255] components */ fun l2d_colors2RGB (iColor)= set iColor = std_clamp iColor 0 16777216; l2d_colorsrgb2c iColor;; /*! Convert the three RGB components to a 24-bits color * * \ingroup l2d_colors * Prototype : fun [I I I] I * * \param I : the red component [0..255] * \param I : the green component [0..255] * \param I : the blue component [0..255] * \return I : the 24-bits color */ fun l2d_colorsRGB2C (iRed, iGreen, iBlue)= set iRed = std_clamp iRed 0 255; set iGreen = std_clamp iGreen 0 255; set iBlue = std_clamp iBlue 0 255; l2d_colorsrgb iRed iGreen iBlue;; /*! Gets the complementary color from a RGB color * * \ingroup l2d_colors * Prototype : fun [I I I] [I I I] * * \param I : the red component [0..255] * \param I : the green component [0..255] * \param I : the blue component [0..255] * \return [I I I] : the three RGB components of the complementary (0..255 for each) */ fun l2d_colorsGetComplFromRGB (iRed, iGreen, iBlue)= set iRed = std_clamp iRed 0 255; set iGreen = std_clamp iGreen 0 255; set iBlue = std_clamp iBlue 0 255; l2d_colorsComplementaryFromRGB iRed iGreen iBlue;; /*! Gets the complementary color from a HSV color * * \ingroup l2d_colors * Prototype : fun [I I I] [I I I] * * \param I : the hue component [0..360] * \param I : the saturation component [0..100] * \param I : the value component [0..100] * \return [I I I] : the three HSV components of the complementary (0..360 for hue, 0..100 for saturation and value) */ fun l2d_colorsGetComplFromHSV (iHue, iSaturation, iValue)= set iHue = std_clamp iHue 0 360; set iSaturation = std_clamp iSaturation 0 100; set iValue = std_clamp iValue 0 100; let l2d_colorsComplementaryFromHSV itof iHue (itof iSaturation)/.100.0 (itof iValue)/.100.0 -> [h s v] in [ftoi h (ftoi s*.100.0) (ftoi v*.100.0)];; /*! Converts a RGB 24-bits color to its CMYK components * * \ingroup l2d_colors * Prototype : fun [I I I] [[I I I I] [I I I I]] * * \param I : the red component [0..255] * \param I : the green component [0..255] * \param I : the blue component [0..255] * \return [[I I I I] [I I I I]] : the four CMYK components (0..100 for each) * - the first tuple returns the components from the 'black' (or 'full') space. It is used by LibreOffice or MS Office by example. * - the second tuple returns the components from the 'white' space. It is used by GIMP or Adobe Photoshop by example. */ fun l2d_colorsConvertRGB2CMYK(iRed, iGreen, iBlue)= set iRed = std_clamp iRed 0 255; set iGreen = std_clamp iGreen 0 255; set iBlue = std_clamp iBlue 0 255; l2d_colors_rgb2cmyk iRed iGreen iBlue;; /*! Converts a CMYK color to its RGB components (8-bits per component) * * \ingroup l2d_colors * Prototype : fun [I I I I I] [I I I] * * \param I : the cyan component [0..100] * \param I : the magenta component [0..100] * \param I : the yellow component [0..100] * \param I : the key (black) component [0..100] * \param I : the space identifier : 1 for CMYK from the 'white' space, other integer from the 'black' space * \return [I I I] : the three RVB components (0..255 for each). */ fun l2d_colorsConvertCMYK2RGB (iCyan, iMagenta, iYellow, iKey, iSpace)= set iCyan = std_clamp iCyan 0 100; set iMagenta = std_clamp iMagenta 0 100; set iYellow = std_clamp iYellow 0 100; set iKey = std_clamp iKey 0 100; l2d_colors_cmyk2rvb iCyan iMagenta iYellow iKey iSpace;; /*! Converts a RGB 24-bits color from integer to hexadecimal values * * \ingroup l2d_colors * Prototype : fun [I I I] [S S S] * * \param I : the red component [0..255] * \param I : the green component [0..255] * \param I : the blue component [0..255] * \return [S S S] : the three hexadecimal components (00..FF for each) */ fun l2d_colorsConvertINT2HEX (iRed, iGreen, iBlue)= set iRed = std_clamp iRed 0 255; set iGreen = std_clamp iGreen 0 255; set iBlue = std_clamp iBlue 0 255; l2d_colors_rgb2hex iRed iGreen iBlue;; /*! Converts a RGB 24-bits color from hexadecimal to integer values * * \ingroup l2d_colors * Prototype : fun [S S S] [I I I] * * \param S : the red component in hex * \param S : the green component in hex * \param S : the blue component in hex * \return [I I I] : the three hexadecimal components (0..255 for each) */ fun l2d_colorsConvertHEX2INT (szRed, szGreen, szBlue)= l2d_colors_hex2int szRed szGreen szBlue;; /*! Gets a basic color from its standardized CSS name. * * black sylver gray white maroon red purple fuchsia green lime olive yellow navy blue teal aqua * \see http://www.w3.org/TR/css3-color/#html4 * * \ingroup l2d_colors * Prototype : fun [S] [S S [I I I]] * * \param S : a css color name * \return [S S [I I I]] : a tuple or nil if the color name is not found in the resources * - S : the same given name in argument * - S : the hexadecimal value * - [I I I] : the three hexadecimal rgb components (0..255 for each) */ fun l2d_colorsFromCssByName (szName)= l2d_colorscss szName;; /*! Converts a HSL color to a RGB color * * \ingroup l2d_colors * Prototype : fun [I I I] [I I I] * * \param I : the hue component [0..360] * \param I : the saturation component [0..100] * \param I : the lightness component [0..100] * \return [I I I] : the three components : red, green, blue (0..255 for each) */ fun l2d_colorsConvertHSL2RGB (iHue, iSaturation, iLightness)= set iHue = std_clamp iHue 0 360; set iSaturation = std_clamp iSaturation 0 100; set iLightness = std_clamp iLightness 0 100; let l2d_colors_hsl2rgb iHue iSaturation iLightness -> [r g b] in [ftoi (r*.255.0) ftoi (g*.255.0) ftoi (b*.255.0)];; /*! Converts a RGB 24-bits color to a HSL color * * \ingroup l2d_colors * Prototype : fun [I I I] [I I I] * * \param I : the red component [0..255] * \param I : the green component [0..255] * \param I : the blue component [0..255] * \return [I I I] : the three components : hue, saturation, lightness (0..100 for each, except hue 0..360) */ fun l2d_colorsConvertRGB2HSL (iRed, iGreen, iBlue)= set iRed = std_clamp iRed 0 255; set iGreen = std_clamp iGreen 0 255; set iBlue = std_clamp iBlue 0 255; let l2d_colors_rgb2hsl iRed iGreen iBlue -> [h s l] in [ftoi (h*.360.0) ftoi (s*.100.0) ftoi (l*.100.0)];; /*! Returns the gray value from a RGB color : "average method" * * The formula is : \f$Gray = (Red + Green + Blue) / 3\f$ * * This is the faster and the simpler method. It gives a reasonably grayscale * equivalent but it is the lesser for the human eye. * * \ingroup l2d_colors * Prototype : fun [I I I] [I I I] * * \param I : the red component [0..255] * \param I : the green component [0..255] * \param I : the blue component [0..255] * \return [I I I] : the three gray RGB components (0..255 for each) */ fun l2d_colorsGrayAverage (iRed, iGreen, iBlue)= set iRed = std_clamp iRed 0 255; set iGreen = std_clamp iGreen 0 255; set iBlue = std_clamp iBlue 0 255; l2d_colorsgrayscaleOne iRed iGreen iBlue;; /*! Returns the gray value from a RGB color : "human eye correction A" * * The formula is : \f$Gray = Red * 0.3 + Green * 0.59 + Blue * 0.11\f$ * * The human eye perceive green more strongly than red, and red more strongly * than blue. The cause is evolutionary biology perspective, much of the * natural world appears in shades of green. The resulting contrast is near * of a photograph from an argentic camera. * * For example, GIMP and Adobe Photoshop use this formula in theirs threatments. * * \ingroup l2d_colors * Prototype : fun [I I I] [I I I] * * \param I : the red component [0..255] * \param I : the green component [0..255] * \param I : the blue component [0..255] * \return [I I I] : the three gray RGB components (0..255 for each) * * \see l2d_colorsGrayHumanB * \see l2d_colorsGrayHumanC */ fun l2d_colorsGrayHumanA (iRed, iGreen, iBlue)= set iRed = std_clamp iRed 0 255; set iGreen = std_clamp iGreen 0 255; set iBlue = std_clamp iBlue 0 255; l2d_colorsgrayscaleTwoA iRed iGreen iBlue;; /*! Returns the gray value from a RGB color : "human eye correction B" * * The formula is : \f$Gray = Red * 0.2126 + Green * 0.7152 + Blue * 0.0722\f$ * * The human eye perceive green more strongly than red, and red more strongly * than blue. The cause is evolutionary biology perspective, much of the * natural world appears in shades of green. * * There is disagreement on the best formula for this type of grayscale conversion. * Here is the definition by the ITU (BT.709) : http://www.itu.int/rec/R-REC-BT.709/en * * \ingroup l2d_colors * Prototype : fun [I I I] [I I I] * * \param I : the red component [0..255] * \param I : the green component [0..255] * \param I : the blue component [0..255] * \return [I I I] : the three gray RGB components (0..255 for each) * * \see l2d_colorsGrayHumanA * \see l2d_colorsGrayHumanC */ fun l2d_colorsGrayHumanB (iRed, iGreen, iBlue)= set iRed = std_clamp iRed 0 255; set iGreen = std_clamp iGreen 0 255; set iBlue = std_clamp iBlue 0 255; l2d_colorsgrayscaleTwoB iRed iGreen iBlue;; /*! Returns the gray value from a RGB color : "human eye correction C" * * The formula is : \f$Gray = Red * 0.299 + Green * 0.587 + Blue * 0.114\f$ * * The human eye perceive green more strongly than red, and red more strongly * than blue. The cause is evolutionary biology perspective, much of the * natural world appears in shades of green. * * There is disagreement on the best formula for this type of grayscale conversion. * Here is the definition by the ITU (BT.601) : http://www.itu.int/rec/R-REC-BT.709/en * * \ingroup l2d_colors * Prototype : fun [I I I] [I I I] * * \param I : the red component [0..255] * \param I : the green component [0..255] * \param I : the blue component [0..255] * \return [I I I] : the three gray RGB components (0..255 for each) * * \see l2d_colorsGrayHumanA * \see l2d_colorsGrayHumanB */ fun l2d_colorsGrayHumanC (iRed, iGreen, iBlue)= set iRed = std_clamp iRed 0 255; set iGreen = std_clamp iGreen 0 255; set iBlue = std_clamp iBlue 0 255; l2d_colorsgrayscaleTwoC iRed iGreen iBlue;; /*! Returns the gray value from a RGB color : "Desaturation" * * The formula is : \f$Gray = (Max(Red, Green, Blue) + Min(Red, Green, Blue)) / 2\f$ * * Desaturating an image works by converting the RGB in HSL format and * forcing the saturation value to zero. This formula is a shortcut for * a more complex conversion. * * The desaturation results in a flatter grayscale image, like with a cheap camera. * * \ingroup l2d_colors * Prototype : fun [I I I] [I I I] * * \param I : the red component [0..255] * \param I : the green component [0..255] * \param I : the blue component [0..255] * \return [I I I] : the three gray RGB components (0..255 for each) */ fun l2d_colorsGrayDesaturation (iRed, iGreen, iBlue)= set iRed = std_clamp iRed 0 255; set iGreen = std_clamp iGreen 0 255; set iBlue = std_clamp iBlue 0 255; l2d_colorsgrayscaleThree iRed iGreen iBlue;; /*! Returns the gray value from a RGB color : "Decomposition" * * The formula is : \f$Gray = Max (Red, Green, Blue)\f$ or \f$Gray = Min (Red, Green, Blue)\f$ * * To decompose an image, the function forces each pixel to the highest * (maximum) or lowest (minimum) of its red, green, and blue values. This * doesn't care which channel the value comes from. * * The "maximum" provides a brighter grayscale image, while the "minimum" * provides a darker one. * * \ingroup l2d_colors * Prototype : fun [I I I I] [I I I] * * \param I : the red component [0..255] * \param I : the green component [0..255] * \param I : the blue component [0..255] * \param I : a flag : 1 with Maximun, 0 with Minimum * \return [I I I] : the three gray RGB components (0..255 for each) */ fun l2d_colorsGrayDecomposition (iRed, iGreen, iBlue, iFlag)= set iRed = std_clamp iRed 0 255; set iGreen = std_clamp iGreen 0 255; set iBlue = std_clamp iBlue 0 255; l2d_colorsgrayscaleFour iRed iGreen iBlue iFlag;; /*! Returns the gray value from a RGB color : "Single gray channel" * * The formula is : \f$Gray = Red\f$ or \f$Gray = Green\f$ or \f$Gray = Blue\f$ * * Usually, this is the worst method. The gray comes from a single color channel. * * \ingroup l2d_colors * Prototype : fun [I I I I] [I I I] * * \param I : the red component [0..255] * \param I : the green component [0..255] * \param I : the blue component [0..255] * \param I : a flag : 0 to red, 1 to green, 2 to blue channel * \return [I I I] : the three gray RGB components (0..255 for each) */ fun l2d_colorsGraySingleChannel (iRed, iGreen, iBlue, iFlag)= set iRed = std_clamp iRed 0 255; set iGreen = std_clamp iGreen 0 255; set iBlue = std_clamp iBlue 0 255; l2d_colorsgrayscaleFive iRed iGreen iBlue iFlag;; /*! Returns the gray value from a RGB color : "Custom shaders" * * This method works by selecting X gray values, equally spread between * zero luminance (black) and full luminance (white). * * \ingroup l2d_colors * Prototype : fun [I I I I] [I I I] * * \param I : the red component [0..255] * \param I : the green component [0..255] * \param I : the blue component [0..255] * \param I : the shaders number : [2..256] : 2 -> black and white until 256 -> like "average method" * \return [I I I] : the three gray RGB components (0..255 for each) */ fun l2d_colorsGrayCustom (iRed, iGreen, iBlue, iFlag)= set iRed = std_clamp iRed 0 255; set iGreen = std_clamp iGreen 0 255; set iBlue = std_clamp iBlue 0 255; l2d_colorsgrayscaleSix iRed iGreen iBlue iFlag;;