//---------------------------------------------------------------------- // Namespace Christo.GFX.Conversion // Author: Christo Greeff // Date: 24/June/2008 //---------------------------------------------------------------------- // 24/June/2008 : New: GFXConversionException, HSL //---------------------------------------------------------------------- using System; using System.Drawing; namespace Christo.GFX.Conversion { /// /// Color Util Exception /// public class GFXConversionException : Exception { public GFXConversionException(string message, Exception innerException) : base(message, innerException) { //ToDo: Implement if needed } } /// /// HSL (Hue/Saturation/Luminance) Class /// public class HSL { #region Private members /// /// private hue /// private double _h; /// /// private saturation /// private double _s; /// /// private luminance /// private double _l; #endregion /// /// Constructor /// public HSL() { try { this.HSLHelper(0, 0, 0); } catch (Exception ee) { throw new GFXConversionException("HSL Constructor Error", ee); } } /// /// Constructor with ARGB color /// /// System.Drawing.Color value public HSL(Color color) { try { this.HSLHelper(color.GetHue() / 360.0, color.GetSaturation(), color.GetBrightness()); } catch (Exception ee) { throw new GFXConversionException("HSL Constructor Error", ee); } } /// /// Constructor with RGB color /// /// Red component with a value from 0 to 255 /// Green component with a value from 0 to 255 /// Blue component with a value from 0 to 255 public HSL(byte R, byte G, byte B) { try { Color temp = Color.FromArgb(R, G, B); this.HSLHelper(temp.GetHue() / 360.0, temp.GetSaturation(), temp.GetBrightness()); } catch (Exception ee) { throw new GFXConversionException("HSL Constructor Error", ee); } } /// /// Constructor with HSL /// /// Varies from magenta - red - yellow - green - cyan - blue - magenta, described as an angle around a circle from 0.0 - 360.0 degrees /// Varies from 0.0 and 1.0 and describes how "grey" the colour is, with 0 being completely unsaturated (grey, white or black) and 1 being completely saturated /// Varies from 0.0 and 1.0 and ranges from black at 0.0, through the standard colour itself at 0.5 to white at 1.0 public HSL(double Hue, double Saturation, double Luminance) { try { this.HSLHelper(Hue, Saturation, Luminance); } catch (Exception ee) { throw new GFXConversionException("HSL Constructor Error", ee); } } /// /// HSL Helper /// /// Varies from magenta - red - yellow - green - cyan - blue - magenta, described as an angle around a circle from 0.0 - 360.0 degrees /// Varies from 0.0 and 1.0 and describes how "grey" the colour is, with 0 being completely unsaturated (grey, white or black) and 1 being completely saturated /// Varies from 0.0 and 1.0 and ranges from black at 0.0, through the standard colour itself at 0.5 to white at 1.0 private void HSLHelper(double Hue, double Saturation, double Luminance) { try { this.H = Hue; this.S = Saturation; this.L = Luminance; } catch (Exception ee) { throw new GFXConversionException("HSL HSLHelper Error", ee); } } /// /// Set helper function /// /// value that must be between 0 and 1 /// double value private double SetHelper(double value) { try { return (value > 1) ? 1.0 : (value < 0) ? 0 : value; } catch (Exception ee) { throw new GFXConversionException("HSL SetHelper Error", ee); } } /// /// Gets or sets the Hue value /// public double H { get { return this._h; } set { this._h = this.SetHelper(value); } } /// /// Gets or sets the Saturation value /// public double S { get { return this._s; } set { this._s = this.SetHelper(value); } } /// /// Gets or sets the Luminance value /// public double L { get { return this._l; } set { this._l = this.SetHelper(value); } } /// /// Convert from the current HSL to RGB /// http://en.wikipedia.org/wiki/HSV_color_space#Conversion_from_HSL_to_RGB /// public Color Color { get { double[] t = new double[] { 0, 0, 0 }; try { double tH = this._h; double tS = this._s; double tL = this._l; if (tS.Equals(0)) { t[0] = t[1] = t[2] = tL; } else { double q, p; q = tL < 0.5 ? tL * (1 + tS) : tL + tS - (tL * tS); p = 2 * tL - q; t[0] = tH + (1.0 / 3.0); t[1] = tH; t[2] = tH - (1.0 / 3.0); for (byte i = 0; i < 3; i++) { t[i] = t[i] < 0 ? t[i] + 1.0 : t[i] > 1 ? t[i] - 1.0 : t[i]; if (t[i] * 6.0 < 1.0) t[i] = p + ((q - p) * 6 * t[i]); else if (t[i] * 2.0 < 1.0) t[i] = q; else if (t[i] * 3.0 < 2.0) t[i] = p + ((q - p) * 6 * ((2.0 / 3.0) - t[i])); else t[i] = p; } } } catch (Exception ee) { throw new GFXConversionException("HSL Color Error", ee); } return Color.FromArgb((int)(t[0] * 255), (int)(t[1] * 255), (int)(t[2] * 255)); } } /// /// Modify the current HSL brightness /// /// brightness value /// HSL private HSL BrightnessHelper(double brightness) { try { this.L = this.L * brightness; } catch (Exception ee) { throw new GFXConversionException("HSL BrightnessHelper Error", ee); } return new HSL(H, S, L); } /// /// Modify the current HSL brightness /// /// brightness value /// HSL public HSL Brightness(double brightness) { return this.BrightnessHelper(brightness); } /// /// Modify the current HSL brightness /// /// brightness value /// Color public Color BrightnessC(double brightness) { return this.BrightnessHelper(brightness).Color; } } }