.net - how to use HSL in Asp.net


Translate

What tools are used for working with HSL colors in .net?


All Answers
  • Translate

    The color struct provides three methods: GetHue, GetSaturation and GetBrightness.

    Bob Powell wrote an interesting piece on this several years ago.

    Bizarre historical note -- "HSL" (and the related "HSV") are one of the many things originating from Xerox's Palo Alto Research Center (PARC) in the 70's, courtesy of Alvy Ray Smith.


  • Translate

    This ColorRGB class provides ways to get and set HSL, along with implicit conversions to and from System.Drawing.Color. It's based on an excellent example from GeekMonkey.com.

    using System;
    using System.Drawing;
    
    namespace RMA.Drawing
    {
      public class ColorRGB
      {
        public byte R;
        public byte G;
        public byte B;
        public byte A;
    
        public ColorRGB()
        {
          R = 255;
          G = 255;
          B = 255;
          A = 255;
        }
    
        public ColorRGB(Color value)
        {
          this.R = value.R;
          this.G = value.G;
          this.B = value.B;
          this.A = value.A;
        }
    
        public static implicit operator Color(ColorRGB rgb)
        {
          Color c = Color.FromArgb(rgb.A, rgb.R, rgb.G, rgb.B);
          return c;
        }
    
        public static explicit operator ColorRGB(Color c)
        {
          return new ColorRGB(c);
        }
    
        // Given H,S,L in range of 0-1
        // Returns a Color (RGB struct) in range of 0-255
        public static ColorRGB FromHSL(double H, double S, double L)
        {
          return FromHSLA(H, S, L, 1.0);
        }
    
        // Given H,S,L,A in range of 0-1
        // Returns a Color (RGB struct) in range of 0-255
        public static ColorRGB FromHSLA(double H, double S, double L, double A)
        {
          double v;
          double r, g, b;
    
          if (A > 1.0)
            A = 1.0;
    
          r = L;   // default to gray
          g = L;
          b = L;
          v = (L <= 0.5) ? (L * (1.0 + S)) : (L + S - L * S);
    
          if (v > 0)
          {
            double m;
            double sv;
            int sextant;
            double fract, vsf, mid1, mid2;
    
            m = L + L - v;
            sv = (v - m) / v;
            H *= 6.0;
            sextant = (int)H;
            fract = H - sextant;
            vsf = v * sv * fract;
            mid1 = m + vsf;
            mid2 = v - vsf;
    
            switch (sextant)
            {
              case 0:
                r = v;
                g = mid1;
                b = m;
                break;
    
              case 1:
                r = mid2;
                g = v;
                b = m;
                break;
    
              case 2:
                r = m;
                g = v;
                b = mid1;
                break;
    
              case 3:
                r = m;
                g = mid2;
                b = v;
                break;
    
              case 4:
                r = mid1;
                g = m;
                b = v;
                break;
    
              case 5:
                r = v;
                g = m;
                b = mid2;
                break;
            }
          }
    
          ColorRGB rgb = new ColorRGB();
          rgb.R = Convert.ToByte(r * 255.0f);
          rgb.G = Convert.ToByte(g * 255.0f);
          rgb.B = Convert.ToByte(b * 255.0f);
          rgb.A = Convert.ToByte(A * 255.0f);
          return rgb;
        }
    
        // Hue in range from 0.0 to 1.0
        public float H
        {
          get
          {
            // Use System.Drawing.Color.GetHue, but divide by 360.0F 
            // because System.Drawing.Color returns hue in degrees (0 - 360)
            // rather than a number between 0 and 1.
            return ((Color)this).GetHue() / 360.0F;
          }
        }
    
        // Saturation in range 0.0 - 1.0
        public float S
        {
          get
          {
            return ((Color)this).GetSaturation();
          }
        }
    
        // Lightness in range 0.0 - 1.0
        public float L
        {
          get
          {
            return ((Color)this).GetBrightness();
          }
        }
      }
    }
    

  • Translate

    In addition to secretGeek's answer, to get a color from HSL values (or vice-versa), you can also use these native function calls (sample code in Visual Basic):

    Public Declare Sub ColorRGBToHLS Lib "shlwapi.dll" _
                                        (ByVal clrRGB As UInteger, _
                                         ByRef pwHue As Short, _
                                         ByRef pwLuminance As Short, _
                                         ByRef pwSaturation As Short)
    Public Declare Function ColorHLSToRGB Lib "shlwapi.dll" _
                                            (ByVal wHue As Short, _
                                             ByVal wLuminance As Short, _
                                             ByVal wSaturation As Short) As UInteger
    

    (using ColorTranslator.ToWin32 and ColorTranslator.FromWin32 when passing/receiving the color argument/result)