Initial Commit
This commit is contained in:
301
Common/Auxiliary/HsbColor.cs
Normal file
301
Common/Auxiliary/HsbColor.cs
Normal file
@@ -0,0 +1,301 @@
|
||||
using System;
|
||||
using System.Windows.Media;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Microsoft.Research.DynamicDataDisplay
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents color in Hue Saturation Brightness color space.
|
||||
/// </summary>
|
||||
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hsb")]
|
||||
[DebuggerDisplay("HSBColor A={Alpha} H={Hue} S={Saturation} B={Brightness}")]
|
||||
public struct HsbColor
|
||||
{
|
||||
private double hue;
|
||||
private double saturation;
|
||||
private double brightness;
|
||||
private double alpha;
|
||||
|
||||
/// <summary>Hue; [0, 360]</summary>
|
||||
public double Hue
|
||||
{
|
||||
get { return hue; }
|
||||
set
|
||||
{
|
||||
if (value < 0)
|
||||
value = 360 - value;
|
||||
|
||||
hue = value % 360;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Saturation; [0, 1]</summary>
|
||||
public double Saturation
|
||||
{
|
||||
get { return saturation; }
|
||||
set { saturation = value; }
|
||||
}
|
||||
|
||||
/// <summary>Brightness; [0, 1]</summary>
|
||||
public double Brightness
|
||||
{
|
||||
get { return brightness; }
|
||||
set { brightness = value; }
|
||||
}
|
||||
|
||||
/// <summary>Alpha; [0, 1]</summary>
|
||||
public double Alpha
|
||||
{
|
||||
get { return alpha; }
|
||||
set { alpha = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HSBColor"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="hue">The hue; [0; 360]</param>
|
||||
/// <param name="saturation">The saturation; [0, 1]</param>
|
||||
/// <param name="brightness">The brightness; [0, 1]</param>
|
||||
public HsbColor(double hue, double saturation, double brightness)
|
||||
{
|
||||
this.hue = hue;
|
||||
this.saturation = saturation;
|
||||
this.brightness = brightness;
|
||||
alpha = 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HSBColor"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="hue">The hue; [0, 360]</param>
|
||||
/// <param name="saturation">The saturation; [0, 1]</param>
|
||||
/// <param name="brightness">The brightness; [0, 1]</param>
|
||||
/// <param name="alpha">The alpha; [0, 1]</param>
|
||||
public HsbColor(double hue, double saturation, double brightness, double alpha)
|
||||
{
|
||||
this.hue = hue;
|
||||
this.saturation = saturation;
|
||||
this.brightness = brightness;
|
||||
this.alpha = alpha;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates HSBColor from the ARGB color.
|
||||
/// </summary>
|
||||
/// <param name="color">The color.</param>
|
||||
/// <returns></returns>
|
||||
public static HsbColor FromArgbColor(Color color)
|
||||
{
|
||||
double limit255 = 255;
|
||||
|
||||
double r = color.R / limit255;
|
||||
double g = color.G / limit255;
|
||||
double b = color.B / limit255;
|
||||
|
||||
double max = Math.Max(Math.Max(r, g), b);
|
||||
double min = Math.Min(Math.Min(r, g), b);
|
||||
|
||||
double len = max - min;
|
||||
|
||||
double brightness = max; // 0.5 * (max + min);
|
||||
double sat;
|
||||
double hue;
|
||||
|
||||
|
||||
if (max == 0 || len == 0)
|
||||
{
|
||||
sat = hue = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
sat = len / max;
|
||||
if (r == max)
|
||||
{
|
||||
hue = (g - b) / len;
|
||||
}
|
||||
else if (g == max)
|
||||
{
|
||||
hue = 2 + (b - r) / len;
|
||||
}
|
||||
else
|
||||
{
|
||||
hue = 4 + (r - g) / len;
|
||||
}
|
||||
}
|
||||
|
||||
hue *= 60;
|
||||
if (hue < 0)
|
||||
hue += 360;
|
||||
|
||||
|
||||
HsbColor res = new HsbColor();
|
||||
res.hue = hue;
|
||||
res.saturation = sat;
|
||||
res.brightness = brightness;
|
||||
res.alpha = color.A / limit255;
|
||||
return res;
|
||||
}
|
||||
|
||||
public static HsbColor FromArgb(int argb)
|
||||
{
|
||||
byte a = (byte)(argb >> 24);
|
||||
byte r = (byte)((argb >> 16) & 0xFF);
|
||||
byte g = (byte)((argb >> 8) & 0xFF);
|
||||
byte b = (byte)(argb & 0xFF);
|
||||
return FromArgbColor(Color.FromArgb(a, r, g, b));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts HSBColor to ARGB color space.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Color ToArgbColor()
|
||||
{
|
||||
double r = 0.0;
|
||||
double g = 0.0;
|
||||
double b = 0.0;
|
||||
double hue = this.hue % 360.0;
|
||||
if (saturation == 0.0)
|
||||
{
|
||||
r = g = b = brightness;
|
||||
}
|
||||
else
|
||||
{
|
||||
double smallHue = hue / 60.0;
|
||||
int smallHueInt = (int)Math.Floor(smallHue);
|
||||
double smallHueFrac = smallHue - smallHueInt;
|
||||
double val1 = brightness * (1.0 - saturation);
|
||||
double val2 = brightness * (1.0 - (saturation * smallHueFrac));
|
||||
double val3 = brightness * (1.0 - (saturation * (1.0 - smallHueFrac)));
|
||||
switch (smallHueInt)
|
||||
{
|
||||
case 0:
|
||||
r = brightness;
|
||||
g = val3;
|
||||
b = val1;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
r = val2;
|
||||
g = brightness;
|
||||
b = val1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
r = val1;
|
||||
g = brightness;
|
||||
b = val3;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
r = val1;
|
||||
g = val2;
|
||||
b = brightness;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
r = val3;
|
||||
g = val1;
|
||||
b = brightness;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
r = brightness;
|
||||
g = val1;
|
||||
b = val2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return Color.FromArgb(
|
||||
(byte)(Math.Round(alpha * 255)),
|
||||
(byte)(Math.Round(r * 255)),
|
||||
(byte)(Math.Round(g * 255)),
|
||||
(byte)(Math.Round(b * 255)));
|
||||
}
|
||||
|
||||
public int ToArgb()
|
||||
{
|
||||
return ToArgbColor().ToArgb();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="System.Object"/> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is HsbColor)
|
||||
{
|
||||
HsbColor c = (HsbColor)obj;
|
||||
return (c.alpha == alpha &&
|
||||
c.brightness == brightness &&
|
||||
c.hue == hue &&
|
||||
c.saturation == saturation);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
|
||||
/// </returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return alpha.GetHashCode() ^
|
||||
brightness.GetHashCode() ^
|
||||
hue.GetHashCode() ^
|
||||
saturation.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator ==.
|
||||
/// </summary>
|
||||
/// <param name="first">The first.</param>
|
||||
/// <param name="second">The second.</param>
|
||||
/// <returns>The result of the operator.</returns>
|
||||
public static bool operator ==(HsbColor first, HsbColor second)
|
||||
{
|
||||
return (first.alpha == second.alpha &&
|
||||
first.brightness == second.brightness &&
|
||||
first.hue == second.hue &&
|
||||
first.saturation == second.saturation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator !=.
|
||||
/// </summary>
|
||||
/// <param name="first">The first.</param>
|
||||
/// <param name="second">The second.</param>
|
||||
/// <returns>The result of the operator.</returns>
|
||||
public static bool operator !=(HsbColor first, HsbColor second)
|
||||
{
|
||||
return (first.alpha != second.alpha ||
|
||||
first.brightness != second.brightness ||
|
||||
first.hue != second.hue ||
|
||||
first.saturation != second.saturation);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ColorExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts the ARGB color to the HSB color.
|
||||
/// </summary>
|
||||
/// <param name="color">The color.</param>
|
||||
/// <returns></returns>
|
||||
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hsb")]
|
||||
public static HsbColor ToHsbColor(this Color color)
|
||||
{
|
||||
return HsbColor.FromArgbColor(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user