|
using System;
using System.Globalization;
using System.Text;
using System.Windows.Media;
namespace WpfRgbHslConversions
{
class Program
{
/* Color conversion algorithms are tasken from
* http://130.113.54.154/~monger/hsl-rgb.html. */
#region Structs
struct ColorHls
{
public double H;
public double L;
public double S;
public double A;
}
#endregion
#region Main Program
static void Main(string[] args)
{
var hexIn = "#FF7E188C";
var rgbColor = HexToRgb(hexIn);
Console.WriteLine("Hex in = {0}", hexIn);
Console.WriteLine();
Console.WriteLine("*** RGB IN ***");
Console.WriteLine("R={0}", rgbColor.R);
Console.WriteLine("G={0}", rgbColor.G);
Console.WriteLine("B={0}", rgbColor.B);
Console.WriteLine("A={0}", rgbColor.A);
Console.WriteLine();
var hlsColor = RgbToHls(rgbColor);
Console.WriteLine("*** HLS OUT ***");
Console.WriteLine("H={0}", hlsColor.H.ToString("#"));
Console.WriteLine("L={0}", hlsColor.L.ToString("P0"));
Console.WriteLine("S={0}", hlsColor.S.ToString("P0"));
Console.WriteLine("A={0}", hlsColor.A.ToString("P0"));
Console.WriteLine();
rgbColor = HlsToRgb(hlsColor);
Console.WriteLine("*** RGB OUT ***");
Console.WriteLine("R={0}", rgbColor.R);
Console.WriteLine("G={0}", rgbColor.G);
Console.WriteLine("B={0}", rgbColor.B);
Console.WriteLine("A={0}", rgbColor.A);
Console.WriteLine();
var hexOut = RgbToHex(rgbColor);
Console.WriteLine("Hex out = {0}", hexOut);
Console.WriteLine();
bool b = (hexOut == hexIn);
Console.WriteLine("Hex out = hex in: {0}", b.ToString());
Console.ReadLine();
}
#endregion
#region RGB-Hex Conversions
/// <summary>
/// Converts a hex-string representation of an RGB color to a WPF Color object.
/// </summary>
/// <param name="hexRgbColor">A hex-string representation of an RGB color.</param>
/// <returns>A WPF Color object.</returns>
public static Color HexToRgb(string hexRgbColor)
{
var rgbColor = new Color();
var s = hexRgbColor.Substring(1, 2);
var i = Int32.Parse(s, NumberStyles.HexNumber);
rgbColor.A = Convert.ToByte(i);
s = hexRgbColor.Substring(3, 2);
i = Int32.Parse(s, NumberStyles.HexNumber);
rgbColor.R = Convert.ToByte(i);
s = hexRgbColor.Substring(5, 2);
i = Int32.Parse(s, NumberStyles.HexNumber);
rgbColor.G = Convert.ToByte(i);
s = hexRgbColor.Substring(7, 2);
i = Int32.Parse(s, NumberStyles.HexNumber);
rgbColor.B = Convert.ToByte(i);
return rgbColor;
}
/// <summary>
/// Converts an RGB value to a hex-string equivalent.
/// </summary>
/// <param name="rgbColor">The WPF Color object to convert.</param>
/// <returns>A hex string that represents the RGB value.</returns>
public static string RgbToHex(Color rgbColor)
{
StringBuilder sb = new StringBuilder("#");
sb.Append(rgbColor.A.ToString("X"));
sb.Append(rgbColor.R.ToString("X"));
sb.Append(rgbColor.G.ToString("X"));
sb.Append(rgbColor.B.ToString("X"));
return sb.ToString();
}
#endregion
#region RGB-HLS Conversions
/// <summary>
/// Converts a WPF RGB color to an HSL color
/// </summary>
/// <param name="rgbColor">The RGB color to convert.</param>
/// <returns>An HSL color object equivalent to the RGB color object passed in.</returns>
static ColorHls RgbToHls(Color rgbColor)
{
// Initialize result
var hlsColor = new ColorHls();
// Convert RGB values to percentages
double r = (double)rgbColor.R / 255;
var g = (double)rgbColor.G / 255;
var b = (double)rgbColor.B / 255;
var a = (double)rgbColor.A / 255;
// Find min and max RGB values
var min = Math.Min(r, Math.Min(g, b));
var max = Math.Max(r, Math.Max(g, b));
var delta = max - min;
/* If max and min are equal, that means we are dealing with
* a shade of gray. So we set H and S to zero, and L to either
* max or min (it doesn't matter which), and then we exit. */
//Special case: Gray
if (max == min)
{
hlsColor.H = 0;
hlsColor.S = 0;
hlsColor.L = max;
return hlsColor;
}
/* If we get to this point, we know we don't have a shade of gray. */
// Set L
hlsColor.L = (min + max) / 2;
// Set S
if(hlsColor.L < 0.5)
{
hlsColor.S = delta / (max + min);
}
else
{
hlsColor.S = delta / (2.0 - max - min);
}
// Set H
if (r == max) hlsColor.H = (g - b) / delta;
if (g == max) hlsColor.H = 2.0 + (b - r) / delta;
if (b == max) hlsColor.H = 4.0 + (r - g) / delta;
hlsColor.H *= 60;
if (hlsColor.H < 0) hlsColor.H += 360;
// Set A
hlsColor.A = a;
// Set return value
return hlsColor;
}
/// <summary>
/// Converts a WPF HSL color to an RGB color
/// </summary>
/// <param name="hslColor">The HSL color to convert.</param>
/// <returns>An RGB color object equivalent to the HSL color object passed in.</returns>
static Color HlsToRgb(ColorHls hlsColor)
{
// Initialize result
var rgbColor = new Color();
/* If S = 0, that means we are dealing with a shade
* of gray. So, we set R, G, and B to L and exit. */
// Special case: Gray
if (hlsColor.S == 0)
{
rgbColor.R = (byte)(hlsColor.L * 255);
rgbColor.G = (byte)(hlsColor.L * 255);
rgbColor.B = (byte)(hlsColor.L * 255);
rgbColor.A = (byte)(hlsColor.A * 255);
return rgbColor;
}
double t1;
if (hlsColor.L < 0.5)
{
t1 = hlsColor.L*(1.0 + hlsColor.S);
}
else
{
t1 = hlsColor.L + hlsColor.S - (hlsColor.L * hlsColor.S);
}
var t2 = 2.0*hlsColor.L - t1;
// Convert H from degrees to a percentage
var h = hlsColor.H / 360;
// Set colors as percentage values
var tR = h + (1.0/3.0);
var r = SetColor(t1, t2, tR);
var tG = h;
var g = SetColor(t1, t2, tG);
var tB = h - (1.0 / 3.0);
var b = SetColor(t1, t2, tB);
// Assign colors to Color object
rgbColor.R = (byte)(r * 255);
rgbColor.G = (byte)(g * 255);
rgbColor.B = (byte)(b * 255);
rgbColor.A = (byte)(hlsColor.A * 255);
// Set return value
return rgbColor;
}
#endregion
#region Utility Methods
/// <summary>
/// Used by the HSL-to-RGB converter.
/// </summary>
/// <param name="t1">A temporary variable.</param>
/// <param name="t2">A temporary variable.</param>
/// <param name="t3">A temporary variable.</param>
/// <returns>An RGB color value, in decimal format.</returns>
private static double SetColor(double t1, double t2, double t3)
{
if (t3 < 0) t3 += 1.0;
if (t3 > 1) t3 -= 1.0;
double color;
if (6.0 * t3 < 1)
{
color = t2 + (t1 - t2) * 6.0 * t3;
}
else if(2.0 * t3 < 1)
{
color = t1;
}
else if(3.0*t3 < 2)
{
color = t2 + (t1 - t2) * ((2.0/3.0) - t3) * 6.0;
}
else
{
color = t2;
}
// Set return value
return color;
}
#endregion
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
David Veeneman is a financial planner and software developer. He is the author of "The Fortune in Your Future" (McGraw-Hill 1998). His company, Foresight Systems, develops planning and financial software.