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