我正在寻找一个算法之间的HSL颜色转换为RGB。

在我看来,HSL不是很广泛地使用,所以我没有太多的运气寻找一个转换器。


当前回答

找到了最简单的方法,蟒蛇来拯救:D

colorsys。Hls_to_rgb (h, l, s) 将颜色从HLS坐标转换为RGB坐标。

其他回答

@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 */

Unity3D c#代码来自Mohsen的回答。

以下是Mohsen用c#编写的针对Unity3D的回答。它改编自上面Alec Thilenius给出的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);
    }

}

Mohsen代码的Java实现

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

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 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;
}

这里是修改后的javascript函数,它在0-360度集输出Hue。

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));

c++实现,性能可能比@Mohsen代码更好。它使用[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;
          }
      }
}