HSL to RGB color conversion

后端 未结 21 2717
忘了有多久
忘了有多久 2020-11-22 01:59

I am looking for a JavaScript / PHP algorithm to convert between HSL color to RGB.

It seems to me that HSL is not very widely used so I am not having much luck search

相关标签:
21条回答
  • 2020-11-22 02:13

    I needed a really light weight one, Its not 100%, but it gets close enough for some usecases.

    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);
    }
    
    0 讨论(0)
  • 2020-11-22 02:15

    Here is the modified javascript function, it outputs Hue in set 0-360 degrees.

    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));
    
    0 讨论(0)
  • 2020-11-22 02:17

    Found the easiest way, python to the rescue :D

    colorsys.hls_to_rgb(h, l, s)

    Convert the color from HLS coordinates to RGB coordinates.

    0 讨论(0)
  • 2020-11-22 02:18

    For when you need RGB to HSV and vice versa instead:

    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)];
    }
    
    0 讨论(0)
  • 2020-11-22 02:19

    C++ implementation with probably better performance than @Mohsen code. It uses a [0-6] range for the hue, avoiding the division and multiplication by 6. S and L range is [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;
              }
          }
    }
    
    0 讨论(0)
  • 2020-11-22 02:19

    With H, S,and L in [0,1] range:

    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 };
        }
    }
    
    0 讨论(0)
提交回复
热议问题