Skip to content

Instantly share code, notes, and snippets.

@chris84948
Created January 14, 2016 20:12
Show Gist options
  • Save chris84948/b2415af42aa8068d0512 to your computer and use it in GitHub Desktop.
Save chris84948/b2415af42aa8068d0512 to your computer and use it in GitHub Desktop.
public class ColorPicker
{
private double _brightness, _saturation, _hue;
private Color mainColor;
public ColorPicker(Color color)
{
this.mainColor = color;
// Use color object from different namespace to get extra methods
var realColor = System.Drawing.Color.FromArgb(color.A, color.R, color.G, color.B);
_brightness = realColor.GetBrightness();
_saturation = realColor.GetSaturation();
_hue = realColor.GetHue();
}
/// <summary>
/// This method takes your color and strips the saturation and brightness out of it
/// If you pass in 100% you will get your color
/// If you pass in 0% you will get white
/// The lower the percentage, the closer to white the color will be
/// </summary>
/// <param name="percent">Percentage value 0 - 100</param>
/// <returns></returns>
public Color GetColorAtPercent(double percent)
{
if (percent <= 0)
return Color.FromArgb(mainColor.A, 255, 255, 255);
if (percent >= 100)
return mainColor;
double reqBrightness = (0.5 - _brightness) * ((100 - percent) / 100) + _brightness;
double reqSaturation = _saturation * (percent / 100);
return ColorFromAHSB(mainColor.A, _hue, reqSaturation, 2 * reqBrightness);
}
/// <summary>
/// For more information on Hue, Saturation and Brightness check out this color picker
/// http://www.colorpicker.com/
///
/// NOTE: Be careful with the range of values passed into this method
/// </summary>
/// <param name="opacity"></param>
/// <param name="hue">
/// Hue value from System.Drawing.Color.GetHue returns a value from 0-360 in the color spectrum.
/// </param>
/// <param name="saturation">
/// Saturation value from System.Drawing.Color.GetSaturation returns a value between 0 and 1
/// 1 = most saturated or most colorful
/// </param>
/// <param name="brightness">
/// This function expects this value to be normalized to 0 - 1.
/// Brightness value when calculated from System.Drawing.Color.GetBrightness returns a value
/// between 0 and 0.5. 0.5 is as bright as the brightness can be.
/// If you are passing it in from GetBrightness, double the value beforehand
/// </param>
/// <returns></returns>
public Color ColorFromAHSB(byte opacity, double hue, double saturation, double brightness)
{
// Basic range checking on these values
if (saturation > 1)
saturation = 1;
if (saturation < 0)
saturation = 0;
if (brightness > 1)
brightness = 1;
if (brightness < 0)
brightness = 0;
if (hue > 360)
hue = hue % 360;
if (hue < 0)
hue = 0;
if (saturation == 0)
{
return Color.FromArgb(opacity, Convert.ToByte(brightness * 255),
Convert.ToByte(brightness * 255), Convert.ToByte(brightness * 255));
}
// the color wheel consists of 6 sectors. Figure out which sector
// you're in.
double sectorPos = hue / 60.0;
int sectorNumber = (int)(Math.Floor(sectorPos));
// get the fractional part of the sector
double fractionalSector = sectorPos - sectorNumber;
// calculate values for the three axes of the color.
double p = brightness * (1.0 - saturation);
double q = brightness * (1.0 - (saturation * fractionalSector));
double t = brightness * (1.0 - (saturation * (1 - fractionalSector)));
// assign the fractional colors to r, g, and b based on the sector
// the angle is in.
switch (sectorNumber)
{
case 0:
return Color.FromArgb(opacity, (byte)(brightness * 255), (byte)(t * 255), (byte)(p * 255));
case 1:
return Color.FromArgb(opacity, (byte)(q * 255), (byte)(brightness * 255), (byte)(p * 255));
case 2:
return Color.FromArgb(opacity, (byte)(p * 255), (byte)(brightness * 255), (byte)(t * 255));
case 3:
return Color.FromArgb(opacity, (byte)(p * 255), (byte)(q * 255), (byte)(brightness * 255));
case 4:
return Color.FromArgb(opacity, (byte)(t * 255), (byte)(p * 255), (byte)(brightness * 255));
case 5:
return Color.FromArgb(opacity, (byte)(brightness * 255), (byte)(p * 255), (byte)(q * 255));
default:
return Color.FromArgb(opacity, (byte)(brightness * 255), (byte)(t * 255), (byte)(p * 255));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment