代码之家  ›  专栏  ›  技术社区  ›  hhafez

HSL到RGB颜色转换[关闭]

  •  151
  • hhafez  · 技术社区  · 16 年前

    我正在寻找一个工具或算法之间的HSL颜色转换为RGB。在我看来,高速铁路并没有被广泛使用,所以我没有太多运气寻找转换器。

    19 回复  |  直到 7 年前
        1
  •  272
  •   Martin Thompson    8 年前

    Garry Tan发布了一个javascript解决方案 his blog (他将其归因于一个现在已经不复存在的mjijackson.com, but is archived here the original author has a gist -感谢用户2441511)。

    代码重新发布如下:

    HSL到RGB:

    /**
     * Converts an HSL color value to RGB. Conversion formula
     * adapted from http://en.wikipedia.org/wiki/HSL_color_space.
     * Assumes h, s, and l are contained in the set [0, 1] and
     * returns r, g, and b in the set [0, 255].
     *
     * @param   {number}  h       The hue
     * @param   {number}  s       The saturation
     * @param   {number}  l       The lightness
     * @return  {Array}           The RGB representation
     */
    function hslToRgb(h, s, l){
        var r, g, b;
    
        if(s == 0){
            r = g = b = l; // achromatic
        }else{
            var hue2rgb = function hue2rgb(p, q, t){
                if(t < 0) t += 1;
                if(t > 1) t -= 1;
                if(t < 1/6) return p + (q - p) * 6 * t;
                if(t < 1/2) return q;
                if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
                return p;
            }
    
            var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
            var p = 2 * l - q;
            r = hue2rgb(p, q, h + 1/3);
            g = hue2rgb(p, q, h);
            b = hue2rgb(p, q, h - 1/3);
        }
    
        return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
    }
    

    RGB到HSL:

    /**
     * Converts an RGB color value to HSL. Conversion formula
     * adapted from http://en.wikipedia.org/wiki/HSL_color_space.
     * Assumes r, g, and b are contained in the set [0, 255] and
     * returns h, s, and l in the set [0, 1].
     *
     * @param   {number}  r       The red color value
     * @param   {number}  g       The green color value
     * @param   {number}  b       The blue color value
     * @return  {Array}           The HSL representation
     */
    function rgbToHsl(r, g, b){
        r /= 255, g /= 255, b /= 255;
        var max = Math.max(r, g, b), min = Math.min(r, g, b);
        var h, s, l = (max + min) / 2;
    
        if(max == min){
            h = s = 0; // achromatic
        }else{
            var d = max - min;
            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
            switch(max){
                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
                case g: h = (b - r) / d + 2; break;
                case b: h = (r - g) / d + 4; break;
            }
            h /= 6;
        }
    
        return [h, s, l];
    }
    
        2
  •  41
  •   hhafez    16 年前

    找到了最简单的方法,python到 rescue D

    colorsys.hls_to_rgb(h, l, s)

    将颜色从HLS坐标转换为RGB坐标。

        3
  •  19
  •   Octavia Togami feoh    10 年前

    文章为 HSL and HSV on wikipedia 包含一些公式。计算有点复杂,所以看一下可能很有用 existing implementations .

        4
  •  12
  •   jameshfisher    12 年前

    如果您正在寻找一个绝对符合hsl和rgb的css语义的东西,您可以使用 the algorithm specified in the CSS 3 specification ,上面写着:

    HOW TO RETURN hsl.to.rgb(h, s, l): 
       SELECT: 
          l<=0.5: PUT l*(s+1) IN m2
          ELSE: PUT l+s-l*s IN m2
       PUT l*2-m2 IN m1
       PUT hue.to.rgb(m1, m2, h+1/3) IN r
       PUT hue.to.rgb(m1, m2, h    ) IN g
       PUT hue.to.rgb(m1, m2, h-1/3) IN b
       RETURN (r, g, b)
    
    HOW TO RETURN hue.to.rgb(m1, m2, h): 
       IF h<0: PUT h+1 IN h
       IF h>1: PUT h-1 IN h
       IF h*6<1: RETURN m1+(m2-m1)*h*6
       IF h*2<1: RETURN m2
       IF h*3<2: RETURN m1+(m2-m1)*(2/3-h)*6
       RETURN m1
    

    我相信这是其他答案的来源。

        5
  •  12
  •   Zweibieren    7 年前

    Mohann代码的Java实现

    请注意,所有整数都声明为float(即1f),必须是float,否则将选择灰色。

    色彩空间转换

     /**
     * Converts an HSL color value to RGB. Conversion formula
     * adapted from http://en.wikipedia.org/wiki/HSL_color_space.
     * Assumes h, s, and l are contained in the set [0, 1] and
     * returns r, g, and b in the set [0, 255].
     *
     * @param h       The hue
     * @param s       The saturation
     * @param l       The lightness
     * @return int array, the RGB representation
     */
    public static int[] hslToRgb(float h, float s, float l){
        float r, g, b;
    
        if (s == 0f) {
            r = g = b = l; // achromatic
        } else {
            float q = l < 0.5f ? l * (1 + s) : l + s - l * s;
            float p = 2 * l - q;
            r = hueToRgb(p, q, h + 1f/3f);
            g = hueToRgb(p, q, h);
            b = hueToRgb(p, q, h - 1f/3f);
        }
        int[] rgb = {to255(r), to255(g), to255(b)};
        return rgb;
    }
    public static int to255(float v) { return (int)Math.min(255,256*v); }
    
    /** Helper method that converts hue to rgb */
    public static float hueToRgb(float p, float q, float t) {
        if (t < 0f)
            t += 1f;
        if (t > 1f)
            t -= 1f;
        if (t < 1f/6f)
            return p + (q - p) * 6f * t;
        if (t < 1f/2f)
            return q;
        if (t < 2f/3f)
            return p + (q - p) * (2f/3f - t) * 6f;
        return p;
    }
    

    RGB到HSL

    /**
     * Converts an RGB color value to HSL. Conversion formula
     * adapted from http://en.wikipedia.org/wiki/HSL_color_space.
     * Assumes pR, pG, and bpBare contained in the set [0, 255] and
     * returns h, s, and l in the set [0, 1].
     *
     * @param pR       The red color value
     * @param pG       The green color value
     * @param pB       The blue color value
     * @return float array, the HSL representation
     */
    public static float[] rgbToHsl(int pR, int pG, int pB) {
        float r = pR / 255f;
        float g = pG / 255f;
        float b = pB / 255f;
    
        float max = (r > g && r > b) ? r : (g > b) ? g : b;
        float min = (r < g && r < b) ? r : (g < b) ? g : b;
    
        float h, s, l;
        l = (max + min) / 2.0f;
    
        if (max == min) {
            h = s = 0.0f;
        } else {
            float d = max - min;
            s = (l > 0.5f) ? d / (2.0f - max - min) : d / (max + min);
    
            if (r > g && r > b)
                h = (g - b) / d + (g < b ? 6.0f : 0.0f);
    
            else if (g > b)
                h = (b - r) / d + 2.0f;
    
            else
                h = (r - g) / d + 4.0f;
    
            h /= 6.0f;
        }
    
        float[] hsl = {h, s, l};
        return hsl;
    }
    
        6
  •  7
  •   Alec Thilenius    12 年前

    C莫森答案的代码。

    这是莫森用C语言回答的密码,如果有人需要的话。注: Color 是自定义类,并且 Vector4 来自OpenTK。两者都很容易被你选择的其他东西取代。

    HSL到RGBA

    /// <summary>
    /// Converts an HSL color value to RGB.
    /// Input: Vector4 ( X: [0.0, 1.0], Y: [0.0, 1.0], Z: [0.0, 1.0], W: [0.0, 1.0] )
    /// Output: Color ( R: [0, 255], G: [0, 255], B: [0, 255], A: [0, 255] )
    /// </summary>
    /// <param name="hsl">Vector4 defining X = h, Y = s, Z = l, W = a. Ranges [0, 1.0]</param>
    /// <returns>RGBA Color. Ranges [0, 255]</returns>
    public static Color HslToRgba(Vector4 hsl)
    {
        float r, g, b;
    
        if (hsl.Y == 0.0f)
            r = g = b = hsl.Z;
    
        else
        {
            var q = hsl.Z < 0.5f ? hsl.Z * (1.0f + hsl.Y) : hsl.Z + hsl.Y - hsl.Z * hsl.Y;
            var p = 2.0f * hsl.Z - q;
            r = HueToRgb(p, q, hsl.X + 1.0f / 3.0f);
            g = HueToRgb(p, q, hsl.X);
            b = HueToRgb(p, q, hsl.X - 1.0f / 3.0f);
        }
    
        return new Color((int)(r * 255), (int)(g * 255), (int)(b * 255), (int)(hsl.W * 255));
    }
    
    // Helper for HslToRgba
    private static float HueToRgb(float p, float q, float t)
    {
        if (t < 0.0f) t += 1.0f;
        if (t > 1.0f) t -= 1.0f;
        if (t < 1.0f / 6.0f) return p + (q - p) * 6.0f * t;
        if (t < 1.0f / 2.0f) return q;
        if (t < 2.0f / 3.0f) return p + (q - p) * (2.0f / 3.0f - t) * 6.0f;
        return p;
    }
    

    RGB到HSL

    /// <summary>
    /// Converts an RGB color value to HSL.
    /// Input: Color ( R: [0, 255], G: [0, 255], B: [0, 255], A: [0, 255] )
    /// Output: Vector4 ( X: [0.0, 1.0], Y: [0.0, 1.0], Z: [0.0, 1.0], W: [0.0, 1.0] )
    /// </summary>
    /// <param name="rgba"></param>
    /// <returns></returns>
    public static Vector4 RgbaToHsl(Color rgba)
    {
        float r = rgba.R / 255.0f;
        float g = rgba.G / 255.0f;
        float b = rgba.B / 255.0f;
    
        float max = (r > g && r > b) ? r : (g > b) ? g : b;
        float min = (r < g && r < b) ? r : (g < b) ? g : b;
    
        float h, s, l;
        h = s = l = (max + min) / 2.0f;
    
        if (max == min)
            h = s = 0.0f;
    
        else
        {
            float d = max - min;
            s = (l > 0.5f) ? d / (2.0f - max - min) : d / (max + min);
    
            if (r > g && r > b)
                h = (g - b) / d + (g < b ? 6.0f : 0.0f);
    
            else if (g > b)
                h = (b - r) / d + 2.0f;
    
            else
                h = (r - g) / d + 4.0f;
    
            h /= 6.0f;
        }
    
        return new Vector4(h, s, l, rgba.A / 255.0f);
    }
    
        7
  •  5
  •   geoff    11 年前

    这就是我做这件事的方式,很容易记住,就是把RGB想象成一个车轮上的三个辐条,相隔120度。

    H = hue (0-360)
    S = saturation (0-1)
    L = luminance (0-1)
    
    R1 = SIN( H ) * L 
    G1 = SIN( H + 120 ) * L 
    B1 = SIN( H + 240 ) * L 
    

    棘手的部分是饱和,这是一个比例下降到这三个平均值。

    AVERAGE = (R1 + G1 + B1) / 3 
    
    R2 = ((R1 - AVERAGE) * S) + AVERAGE 
    G2 = ((G1 - AVERAGE) * S) + AVERAGE 
    B2 = ((B1 - AVERAGE) * S) + AVERAGE 
    
    RED = R2 * 255 
    GREEN = G2 * 255 
    BLUE = B2 * 255 
    
        8
  •  5
  •   Community Mohan Dere    8 年前

    PHP实现 Chris's C# Code

    也从 here 这很好地解释了它的数学原理。

    这基本上是一系列与HSL(色调饱和度亮度)转换的函数。

    在php 5.6.15上测试和工作

    DR :可以找到完整代码 here on Pastebin .


    十六进制到HSL

    输入:十六进制颜色格式:[]0f4或[]00ff44(磅符号可选)
    输出:hsl(度、百分比、百分比)

    /**
     * Input: hex color
     * Output: hsl(in ranges from 0-1)
     * 
     * Takes the hex, converts it to RGB, and sends
     * it to RGBToHsl.  Returns the output.
     * 
    */
    function hexToHsl($hex) {
        $r = "";
        $g = "";
        $b = "";
    
        $hex = str_replace('#', '', $hex);
    
        if (strlen($hex) == 3) {
            $r = substr($hex, 0, 1);
            $r = $r . $r;
            $g = substr($hex, 1, 1);
            $g = $g . $g;
            $b = substr($hex, 2, 1);
            $b = $b . $b;
        } elseif (strlen($hex) == 6) {
            $r = substr($hex, 0, 2);
            $g = substr($hex, 2, 2);
            $b = substr($hex, 4, 2);
        } else {
            return false;
        }
    
        $r = hexdec($r);
        $g = hexdec($g);
        $b = hexdec($b);
    
        $hsl =  rgbToHsl($r,$g,$b);
        return $hsl;
    }
    

    RGB到HSL

    输入:0-255范围内的RGB 输出:hsl,以度、百分比、百分比表示。

    /**
     * 
     *Credits:
     * https://stackoverflow.com/questions/4793729/rgb-to-hsl-and-back-calculation-problems
     * http://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/
     *
     * Called by hexToHsl by default.
     *
     * Converts an RGB color value to HSL. Conversion formula
     * adapted from http://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/.
     * Assumes r, g, and b are contained in the range [0 - 255] and
     * returns h, s, and l in the format Degrees, Percent, Percent.
     *
     * @param   Number  r       The red color value
     * @param   Number  g       The green color value
     * @param   Number  b       The blue color value
     * @return  Array           The HSL representation
    */
    function rgbToHsl($r, $g, $b){  
        //For the calculation, rgb needs to be in the range from 0 to 1. To convert, divide by 255 (ff). 
        $r /= 255;
        $g /= 255;
        $b /= 255;
    
        $myMax = max($r, $g, $b);
        $myMin = min($r, $g, $b);
    
        $maxAdd = ($myMax + $myMin);
        $maxSub = ($myMax - $myMin);
    
        //luminence is (max + min)/2
        $h = 0;
        $s = 0;
        $l = ($maxAdd / 2.0);
    
        //if all the numbers are equal, there is no saturation (greyscale).
        if($myMin != $myMax){
            if ($l < 0.5) {
                $s = ($maxSub / $maxAdd);
            } else {
                $s = (2.0 - $myMax - $myMin); //note order of opperations - can't use $maxSub here
                $s = ($maxSub / $s);
            }
    
            //find hue
            switch($myMax){
                case $r: 
                    $h = ($g - $b);
                    $h = ($h / $maxSub);
                    break;
                case $g: 
                    $h = ($b - $r); 
                    $h = ($h / $maxSub);
                    $h = ($h + 2.0);
                    break;
                case $b: 
                    $h = ($r - $g);
                    $h = ($h / $maxSub); 
                    $h = ($h + 4.0);
                    break;
            } 
        }
    
        $hsl = hslToDegPercPerc($h, $s, $l);
        return $hsl;
    }
    

    HSL(0-1范围)到度、百分比、百分比格式

    对于数学计算,HSL在0-1范围内更容易处理,但是对于人类可读性,它在度、百分比、百分比上更容易处理。此函数在0-1范围内获取HSL,并以度、百分比和百分比返回HSL。

    /**
     * Input: HSL in ranges 0-1.
     * Output: HSL in format Deg, Perc, Perc.
     * 
     * Note: rgbToHsl calls this function by default.
     * 
     * Multiplies $h by 60, and $s and $l by 100.
     */
    function hslToDegPercPerc($h, $s, $l) {
        //convert h to degrees
        $h *= 60;
    
        if ($h < 0) {
            $h += 360;
        }
    
        //convert s and l to percentage
        $s *= 100;
        $l *= 100;
    
        $hsl['h'] = $h;
        $hsl['s'] = $s;
        $hsl['l'] = $l;
        return $hsl;
    }
    

    hsl(度数、百分比、百分比格式)到hsl,范围为0-1

    此函数将格式为度、百分比、百分比的HSL转换为范围0-1,以便于计算。

    /**
     * Input: HSL in format Deg, Perc, Perc
     * Output: An array containing HSL in ranges 0-1
     * 
     * Divides $h by 60, and $s and $l by 100.
     * 
     * hslToRgb calls this by default.
    */
    function degPercPercToHsl($h, $s, $l) { 
        //convert h, s, and l back to the 0-1 range
    
        //convert the hue's 360 degrees in a circle to 1
        $h /= 360;
    
        //convert the saturation and lightness to the 0-1 
        //range by multiplying by 100
        $s /= 100;
        $l /= 100;
    
        $hsl['h'] =  $h;
        $hsl['s'] = $s;
        $hsl['l'] = $l;
    
        return $hsl;
    }
    

    色彩空间转换

    以度、百分比、百分比格式输入:hsl 输出:格式为RGB 255, 255, 255 .

    /**
     * Converts an HSL color value to RGB. Conversion formula
     * adapted from http://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/.
     * Assumes h, s, and l are in the format Degrees,
     * Percent, Percent, and returns r, g, and b in 
     * the range [0 - 255].
     *
     * Called by hslToHex by default.
     *
     * Calls: 
     *   degPercPercToHsl
     *   hueToRgb
     *
     * @param   Number  h       The hue value
     * @param   Number  s       The saturation level
     * @param   Number  l       The luminence
     * @return  Array           The RGB representation
     */
    function hslToRgb($h, $s, $l){
        $hsl = degPercPercToHsl($h, $s, $l);
        $h = $hsl['h'];
        $s = $hsl['s'];
        $l = $hsl['l'];
    
        //If there's no saturation, the color is a greyscale,
        //so all three RGB values can be set to the lightness.
        //(Hue doesn't matter, because it's grey, not color)
        if ($s == 0) {
            $r = $l * 255;
            $g = $l * 255;
            $b = $l * 255;
        }
        else {
            //calculate some temperary variables to make the 
            //calculation eaisier.
            if ($l < 0.5) {
                $temp2 = $l * (1 + $s);
            } else {
                $temp2 = ($l + $s) - ($s * $l);
            }
            $temp1 = 2 * $l - $temp2;
    
            //run the calculated vars through hueToRgb to
            //calculate the RGB value.  Note that for the Red
            //value, we add a third (120 degrees), to adjust 
            //the hue to the correct section of the circle for
            //red.  Simalarly, for blue, we subtract 1/3.
            $r = 255 * hueToRgb($temp1, $temp2, $h + (1 / 3));
            $g = 255 * hueToRgb($temp1, $temp2, $h);
            $b = 255 * hueToRgb($temp1, $temp2, $h - (1 / 3));
        }
    
        $rgb['r'] = $r;
        $rgb['g'] = $g;
        $rgb['b'] = $b;
    
        return $rgb;
    }
    

    色调到RGB

    hsltorgb调用此函数将色调转换为单独的rgb值。

    /**
     * Converts an HSL hue to it's RGB value.  
     *
     * Input: $temp1 and $temp2 - temperary vars based on 
     * whether the lumanence is less than 0.5, and 
     * calculated using the saturation and luminence
     * values.
     *  $hue - the hue (to be converted to an RGB 
     * value)  For red, add 1/3 to the hue, green 
     * leave it alone, and blue you subtract 1/3 
     * from the hue.
     *
     * Output: One RGB value.
     *
     * Thanks to Easy RGB for this function (Hue_2_RGB).
     * http://www.easyrgb.com/index.php?X=MATH&$h=19#text19
     *
    */
    function hueToRgb($temp1, $temp2, $hue) {
        if ($hue < 0) { 
            $hue += 1;
        }
        if ($hue > 1) {
            $hue -= 1;
        }
    
        if ((6 * $hue) < 1 ) {
            return ($temp1 + ($temp2 - $temp1) * 6 * $hue);
        } elseif ((2 * $hue) < 1 ) {
            return $temp2;
        } elseif ((3 * $hue) < 2 ) {
            return ($temp1 + ($temp2 - $temp1) * ((2 / 3) - $hue) * 6);
        }
        return $temp1;
    }
    

    HSL到十六进制

    以度、百分比、百分比格式输入:hsl 输出:十六进制格式 00ff22 (无磅符号)。

    转换为RGB,然后分别转换为十六进制。

    /**
     * Converts HSL to Hex by converting it to 
     * RGB, then converting that to hex.
     * 
     * string hslToHex($h, $s, $l[, $prependPound = true]
     * 
     * $h is the Degrees value of the Hue
     * $s is the Percentage value of the Saturation
     * $l is the Percentage value of the Lightness
     * $prependPound is a bool, whether you want a pound 
     *  sign prepended. (optional - default=true)
     *
     * Calls: 
     *   hslToRgb
     *
     * Output: Hex in the format: #00ff88 (with 
     * pound sign).  Rounded to the nearest whole
     * number.
    */
    function hslToHex($h, $s, $l, $prependPound = true) {
        //convert hsl to rgb
        $rgb = hslToRgb($h,$s,$l);
    
        //convert rgb to hex
        $hexR = $rgb['r'];
        $hexG = $rgb['g'];
        $hexB = $rgb['b'];
    
        //round to the nearest whole number
        $hexR = round($hexR);
        $hexG = round($hexG);
        $hexB = round($hexB);
    
        //convert to hex
        $hexR = dechex($hexR);
        $hexG = dechex($hexG);
        $hexB = dechex($hexB);
    
        //check for a non-two string length
        //if it's 1, we can just prepend a
        //0, but if it is anything else non-2,
        //it must return false, as we don't 
        //know what format it is in.
        if (strlen($hexR) != 2) {
            if (strlen($hexR) == 1) {
                //probably in format #0f4, etc.
                $hexR = "0" . $hexR;
            } else {
                //unknown format
                return false;
            }
        }
        if (strlen($hexG) != 2) {
            if (strlen($hexG) == 1) {
                $hexG = "0" . $hexG;
            } else {
                return false;
            }
        }
        if (strlen($hexB) != 2) {
            if (strlen($hexB) == 1) {
                $hexB = "0" . $hexB;
            } else {
                return false;
            }
        }
    
        //if prependPound is set, will prepend a
        //# sign to the beginning of the hex code.
        //(default = true)
        $hex = "";
        if ($prependPound) {
            $hex = "#";
        }
    
        $hex = $hex . $hexR . $hexG . $hexB;
    
        return $hex;
    }
    
        9
  •  3
  •   Terra Ashley    9 年前

    下面是glsl中一个快速、超简单、无分支的版本:

    vec3 hsl2rgb( vec3 c ) {
        vec3 rgb = clamp(abs(mod(c.x*6.0 + vec3(0.0, 4.0, 2.0), 6.0)-3.0)-1.0, 0.0, 1.0);
        return c.z + c.y * (rgb-0.5)*(1.0-abs(2.0*c.z-1.0));
    }
    

    不会比那个短很多~


    链接到原始概念证明: https://www.shadertoy.com/view/XljGzV

    (免责声明:不是我的代码!)

        10
  •  2
  •   zeros-and-ones    11 年前

    这里是修改后的javascript函数,它输出设置为0-360度的色调。

    function rgbToHsl(r, g, b) {
          r /= 255, g /= 255, b /= 255;
          var max = Math.max(r, g, b), min = Math.min(r, g, b);
          var h, s, l = (max + min) / 2;
    
          if(max == min){
              h = s = 0; // achromatic
          } else {
              var d = max - min;
              s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
              switch(max){
                  case r: h = (g - b) / d ; break;
                  case g: h = 2 + ( (b - r) / d); break;
                  case b: h = 4 + ( (r - g) / d); break;
              }
              h*=60;
              if (h < 0) h +=360;
          }
         return([h, s, l]);
      }  
    alert(rgbToHsl(125,115,145));
    
        11
  •  1
  •   Erik    12 年前

    当您需要RGB到HSV,反之亦然时:

    function rgbToHsv(r, g, b)
    {
        r /= 255, g /= 255, b /= 255;
    
        var min = Math.min(r, g, b),
        max = Math.max(r, g, b),
        delta = max - min,
        h = 0, s = 0, v = max;
    
        if (min != max)
        {
            s = (delta / max);
    
            switch (max)
            {
                case r: h = (g - b) / delta + (g < b ? 6 : 0); break;
                case g: h = (b - r) / delta + 2; break;
                case b: h = (r - g) / delta + 4; break;
            }
    
            h /= 6;
        }
    
        return [h, s, v];
    }
    
    function hsvToRgb(h, s, v)
    {
        var step = h / (1 / 6),
        pos = step - Math.floor(step), // the hue position within the current step
        m = (Math.floor(step) % 2) ? (1 - pos) * v : pos * v, // mix color value adjusted to the brightness(v)
        max = 1 * v,
        min = (1 - s) * v,
        med = m + ((1 - s) * (v - m)),
        r, g, b;
    
        switch (Math.floor(step))
        {
            case 0:
                r = max;
                g = med;
                b = min;
                break;
            case 1:
                r = med;
                g = max;
                b = min;
                break;
            case 2:
                r = min;
                g = max;
                b = med;
                break;
            case 3:
                r = min;
                g = med;
                b = max;
                break;
            case 4:
                r = med;
                g = min;
                b = max;
                break;
            case 5:
                r = max;
                g = min;
                b = med;
                break;
        }
    
        return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
    }
    
        12
  •  1
  •   James Allen    10 年前

    Unity3d C代码来自Mohsen的答案。

    这是Mohsen在C中的答案代码,专门针对Unity3D。它是根据上面AlecThilenius给出的C答案改编的。

    using UnityEngine;
    using System.Collections;
    
    public class ColorTools {
    
        /// <summary>
        /// Converts an HSL color value to RGB.
        /// Input: Vector4 ( X: [0.0, 1.0], Y: [0.0, 1.0], Z: [0.0, 1.0], W: [0.0, 1.0] )**strong text**
        /// Output: Color ( R: [0.0, 1.0], G: [0.0, 1.0], B: [0.0, 1.0], A: [0.0, 1.0] )
        /// </summary>
        /// <param name="hsl">Vector4 defining X = h, Y = s, Z = l, W = a. Ranges [0, 1.0]</param>
        /// <returns>RGBA Color. Ranges [0.0, 1.0]</returns>
        public static Color HslToRgba(Vector4 hsl)
        {
            float r, g, b;
    
            if (hsl.y == 0.0f)
                r = g = b = hsl.z;
            else
            {
                var q = hsl.z < 0.5f ? hsl.z * (1.0f + hsl.y) : hsl.z + hsl.y - hsl.z * hsl.y;
                var p = 2.0f * hsl.z - q;
                r = HueToRgb(p, q, hsl.x + 1.0f / 3.0f);
                g = HueToRgb(p, q, hsl.x);
                b = HueToRgb(p, q, hsl.x - 1.0f / 3.0f);
            }
    
            return new Color(r, g, b, hsl.w);
        }
    
        // Helper for HslToRgba
        private static float HueToRgb(float p, float q, float t)
        {
            if (t < 0.0f) t += 1.0f;
            if (t > 1.0f) t -= 1.0f;
            if (t < 1.0f / 6.0f) return p + (q - p) * 6.0f * t;
            if (t < 1.0f / 2.0f) return q;
            if (t < 2.0f / 3.0f) return p + (q - p) * (2.0f / 3.0f - t) * 6.0f;
            return p;
        }
    
        /// <summary>
        /// Converts an RGB color value to HSL.
        /// Input: Color ( R: [0.0, 1.0], G: [0.0, 1.0], B: [0.0, 1.0], A: [0.0, 1.0] )
        /// Output: Vector4 ( X: [0.0, 1.0], Y: [0.0, 1.0], Z: [0.0, 1.0], W: [0.0, 1.0] )
        /// </summary>
        /// <param name="rgba"></param>
        /// <returns></returns>
        public static Vector4 RgbaToHsl(Color rgba)
        {
    
            float max = (rgba.r > rgba.g && rgba.r > rgba.b) ? rgba.r : 
                (rgba.g > rgba.b) ? rgba.g : rgba.b;
            float min = (rgba.r < rgba.g && rgba.r < rgba.b) ? rgba.r : 
                (rgba.g < rgba.b) ? rgba.g : rgba.b;
    
            float h, s, l;
            h = s = l = (max + min) / 2.0f;
    
            if (max == min)
                h = s = 0.0f;
            else
            {
                float d = max - min;
                s = (l > 0.5f) ? d / (2.0f - max - min) : d / (max + min);
    
                if (rgba.r > rgba.g && rgba.r > rgba.b)
                    h = (rgba.g - rgba.b) / d + (rgba.g < rgba.b ? 6.0f : 0.0f);
    
                else if (rgba.g > rgba.b)
                    h = (rgba.b - rgba.r) / d + 2.0f;
    
                else
                    h = (rgba.r - rgba.g) / d + 4.0f;
    
                h /= 6.0f;
            }
    
            return new Vector4(h, s, l, rgba.a);
        }
    
    }
    
        13
  •  1
  •   0x000f    10 年前

    对于所有说加里谭解决方案转换不正确的从RGB到HSL和回来。因为他在代码中漏掉了部分数字。 我修正了他的代码(javascript)。 很抱歉链接到俄语,但英语不在- HSL-wiki

    function toHsl(r, g, b)
    {
        r /= 255.0;
        g /= 255.0;
        b /= 255.0;
        var max = Math.max(r, g, b);
        var min = Math.min(r, g, b);
        var h, s, l = (max + min) / 2.0;
    
        if(max == min)
        {
            h = s = 0; 
        }
        else
        {
            var d = max - min;
            s = (l > 0.5 ? d / (2.0 - max - min) : d / (max + min));
    
            if(max == r && g >= b)
            {
                h = 1.0472 * (g - b) / d ;
            }
            else if(max == r && g < b)
            {
                h = 1.0472 * (g - b) / d + 6.2832;
            }
            else if(max == g)
            {
                h = 1.0472 * (b - r) / d + 2.0944;
            }
            else if(max == b)
            {
                h = 1.0472 * (r - g) / d + 4.1888;
            }
        }
        return {
            str: 'hsl(' + parseInt(h / 6.2832 * 360.0 + 0.5) + ',' + parseInt(s * 100.0 + 0.5) + '%,' + parseInt(l * 100.0 + 0.5) + '%)',
            obj: { h: parseInt(h / 6.2832 * 360.0 + 0.5), s: parseInt(s * 100.0 + 0.5), l: parseInt(l * 100.0 + 0.5) }
        };
    };
    
        14
  •  1
  •   ernbrn    9 年前

    我从布兰登·马蒂斯那里得到的 HSL Picker 源代码。

    它是 originally written in CoffeeScript . 我使用一个在线转换器将它转换为javascript,并使用这个机制来验证用户输入的是有效的RGB值。这个答案适用于我的用例,因为我发现这个帖子中投票最多的答案不能产生有效的HSL值。

    注意,它返回 hsla 值,与 a 表示不透明度/透明度。 0 完全透明,并且 1 完全不透明的

    function rgbToHsl(rgb) {
      var a, add, b, diff, g, h, hue, l, lum, max, min, r, s, sat;
      r = parseFloat(rgb[0]) / 255;
      g = parseFloat(rgb[1]) / 255;
      b = parseFloat(rgb[2]) / 255;
      max = Math.max(r, g, b);
      min = Math.min(r, g, b);
      diff = max - min;
      add = max + min;
      hue = min === max ? 0 : r === max ? ((60 * (g - b) / diff) + 360) % 360 : g === max ? (60 * (b - r) / diff) + 120 : (60 * (r - g) / diff) + 240;
      lum = 0.5 * add;
      sat = lum === 0 ? 0 : lum === 1 ? 1 : lum <= 0.5 ? diff / add : diff / (2 - add);
      h = Math.round(hue);
      s = Math.round(sat * 100);
      l = Math.round(lum * 100);
      a = parseFloat(rgb[3]) || 1;
      return [h, s, l, a];
    }
    
        15
  •  0
  •   sboisse    13 年前

    H、S和L在[0,1]范围内:

    ConvertHslToRgb: function (iHsl)
    {
        var min, sv, sextant, fract, vsf;
    
        var v = (iHsl.l <= 0.5) ? (iHsl.l * (1 + iHsl.s)) : (iHsl.l + iHsl.s - iHsl.l * iHsl.s);
        if (v === 0)
            return { Red: 0, Green: 0, Blue: 0 };
    
        min = 2 * iHsl.l - v;
        sv = (v - min) / v;
        var h = (6 * iHsl.h) % 6;
        sextant = Math.floor(h);
        fract = h - sextant;
        vsf = v * sv * fract;
    
        switch (sextant)
        {
            case 0: return { r: v, g: min + vsf, b: min };
            case 1: return { r: v - vsf, g: v, b: min };
            case 2: return { r: min, g: v, b: min + vsf };
            case 3: return { r: min, g: v - vsf, b: v };
            case 4: return { r: min + vsf, g: min, b: v };
            case 5: return { r: v, g: min, b: v - vsf };
        }
    }
    
        16
  •  0
  •   BjarkeCK    10 年前

    我需要一个非常轻的,不是100%,但对于一些用例来说已经足够接近了。

    float3 Hue(float h, float s, float l)
    {
        float r = max(cos(h * 2 * UNITY_PI) * 0.5 + 0.5, 0);
        float g = max(cos((h + 0.666666) * 2 * UNITY_PI) * 0.5 + 0.5, 0);
        float b = max(cos((h + 0.333333) * 2 * UNITY_PI) * 0.5 + 0.5, 0);
        float gray = 0.2989 * r + 0.5870 * g + 0.1140 * b;
        return lerp(gray, float3(r, g, b), s) * smoothstep(0, 0.5, l) + 1 * smoothstep(0.5, 1, l);
    }
    
        17
  •  0
  •   Swiss Mister    9 年前

    @mohsen代码的PHP实现(包括test!)

    很抱歉重新发布。但我真的没有看到任何其他实现能够提供我需要的质量。

    /**
     * Converts an HSL color value to RGB. Conversion formula
     * adapted from http://en.wikipedia.org/wiki/HSL_color_space.
     * Assumes h, s, and l are contained in the set [0, 1] and
     * returns r, g, and b in the set [0, 255].
     *
     * @param   {number}  h       The hue
     * @param   {number}  s       The saturation
     * @param   {number}  l       The lightness
     * @return  {Array}           The RGB representation
     */
    
    function hue2rgb($p, $q, $t){
                if($t < 0) $t += 1;
                if($t > 1) $t -= 1;
                if($t < 1/6) return $p + ($q - $p) * 6 * $t;
                if($t < 1/2) return $q;
                if($t < 2/3) return $p + ($q - $p) * (2/3 - $t) * 6;
                return $p;
            }
    function hslToRgb($h, $s, $l){
        if($s == 0){
            $r = $l;
            $g = $l;
            $b = $l; // achromatic
        }else{
            $q = $l < 0.5 ? $l * (1 + $s) : $l + $s - $l * $s;
            $p = 2 * $l - $q;
            $r = hue2rgb($p, $q, $h + 1/3);
            $g = hue2rgb($p, $q, $h);
            $b = hue2rgb($p, $q, $h - 1/3);
        }
    
        return array(round($r * 255), round($g * 255), round($b * 255));
    }
    
    /* Uncomment to test * /
    for ($i=0;$i<360;$i++) {
      $rgb=hslToRgb($i/360, 1, .9);
      echo '<div style="background-color:rgb(' .$rgb[0] . ', ' . $rgb[1] . ', ' . $rgb[2] . ');padding:2px;"></div>';
    }
    /* End Test */
    
        18
  •  0
  •   stoke motor    9 年前

    HSL在javascript中设置的颜色值将立即 转换为rgb_a之后,您需要做的就是访问 计算样式值

    document.body.style.color = 'hsla(44, 100%, 50%, 0.8)';
    
    console.log(window.getComputedStyle(document.body).color);
    
    // displays: rgba(255, 187, 0, 0.8)
    

    从技术上讲,我想,这甚至不是 任何 代码行-它是 自动完成。所以,根据你的环境,你 可能就这样逃脱了。不是没有 这里有很多深思熟虑的回答。我不知道你的 目标是。

    现在,如果您想从RBG_A转换为HSL_A呢?

        19
  •  0
  •   Adriel Jr    8 年前

    C++实现,其性能可能优于@莫森代码。它使用[0-6]范围作为色调,避免了6的除法和乘法。S和L范围为[0,1]

    void fromRGBtoHSL(float rgb[], float hsl[])
    {
         const float maxRGB = max(rgb[0], max(rgb[1], rgb[2]));
         const float minRGB = min(rgb[0], min(rgb[1], rgb[2]));
         const float delta2 = maxRGB + minRGB;
         hsl[2] = delta2 * 0.5f;
    
         const float delta = maxRGB - minRGB;
         if (delta < FLT_MIN)
             hsl[0] = hsl[1] = 0.0f;
         else
         {
             hsl[1] = delta / (hsl[2] > 0.5f ? 2.0f - delta2 : delta2);
             if (rgb[0] >= maxRGB)
             {
                 hsl[0] = (rgb[1] - rgb[2]) / delta;
                 if (hsl[0] < 0.0f)
                     hsl[0] += 6.0f;
             }
             else if (rgb[1] >= maxRGB)
                 hsl[0] = 2.0f + (rgb[2] - rgb[0]) / delta;
             else
                 hsl[0] = 4.0f + (rgb[0] - rgb[1]) / delta;
         }
    }
    
    void fromHSLtoRGB(const float hsl[], float rgb[])
    {
        if(hsl[1] < FLT_MIN)
            rgb[0] = rgb[1] = rgb[2] = hsl[2];
        else if(hsl[2] < FLT_MIN)
            rgb[0] = rgb[1] = rgb[2] = 0.0f;
        else
        {
            const float q = hsl[2] < 0.5f ? hsl[2] * (1.0f + hsl[1]) : hsl[2] + hsl[1] - hsl[2] * hsl[1];
            const float p = 2.0f * hsl[2] - q;
            float t[] = {hsl[0] + 2.0f, hsl[0], hsl[0] - 2.0f};
    
            for(int i=0; i<3; ++i)
            {
                if(t[i] < 0.0f)
                    t[i] += 6.0f;
                else if(t[i] > 6.0f)
                    t[i] -= 6.0f;
    
                if(t[i] < 1.0f)
                    rgb[i] = p + (q - p) * t[i];
                else if(t[i] < 3.0f)
                    rgb[i] = q;
                else if(t[i] < 4.0f)
                    rgb[i] = p + (q - p) * (4.0f - t[i]);
                else
                    rgb[i] = p;
              }
          }
    }