Skip to content

Commit

Permalink
Fixing HSL methods that were incorrectly using HSB (#143)
Browse files Browse the repository at this point in the history
  • Loading branch information
CoryCharlton committed Jun 26, 2024
1 parent bd2d0ae commit 8f0ffd7
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -95,5 +95,32 @@ public void TestRgbFormat(byte r, byte g, byte b, byte order, byte numR, byte nu
// Assert
Assert.AreEqual(correctResult, result);
}

[TestMethod]
public void GetBrightness_returns_correct_value()
{
var color = Color.FromArgb(38, 196, 103);
var result = color.GetBrightness();

Assert.AreEqual(45, (int)(result * 100));
}

[TestMethod]
public void GetHue_returns_correct_value()
{
var color = Color.FromArgb(38, 196, 103);
var result = color.GetHue();

Assert.AreEqual(144, (int)result);
}

[TestMethod]
public void GetSaturation_returns_correct_value()
{
var color = Color.FromArgb(38, 196, 103);
var result = color.GetSaturation();

Assert.AreEqual(67, (int)(result * 100));
}
}
}
131 changes: 81 additions & 50 deletions nanoFramework.Graphics.Core/System/Drawing/Color.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@
// See LICENSE file in the project root for full license information.
//

using System;
using System.Reflection;

namespace System.Drawing
{
/// <summary>
/// Represents an ARGB (alpha, red, green, blue) color.
/// </summary>
public struct Color
public readonly struct Color
{
private readonly uint _color;

Expand Down Expand Up @@ -1154,24 +1153,24 @@ internal Color(uint color)
#endregion Known colors

/// <summary>
/// Gets the alpha component value of this System.Drawing.Color structure.
/// Gets the alpha component value of this <see cref="Color"/> structure.
/// </summary>
public byte A { get => (byte)(_color >> 24); }
public byte A => (byte)(_color >> 24);

/// <summary>
/// Gets the blue component value of this System.Drawing.Color structure.
/// Gets the blue component value of this <see cref="Color"/> structure.
/// </summary>
public byte B { get => (byte)_color; }
public byte B => (byte)_color;

/// <summary>
/// Gets the red component value of this System.Drawing.Color structure.
/// Gets the red component value of this <see cref="Color"/> structure.
/// </summary>
public byte R { get => (byte)(_color >> 16); }
public byte R => (byte)(_color >> 16);

/// <summary>
/// Gets the green component value of this System.Drawing.Color structure.
/// Gets the green component value of this <see cref="Color"/> structure.
/// </summary>
public byte G { get => (byte)(_color >> 8); }
public byte G => (byte)(_color >> 8);

/// <summary>
/// Creates a System.Drawing.Color structure from the specified 8-bit color values
Expand Down Expand Up @@ -1365,18 +1364,39 @@ public static bool TryGetColor(string strColor, out Color color)
/// <returns>true if the current object is equal to other; otherwise, false.</returns>
public override bool Equals(object other) => _color == ((Color)other)._color;

private static void MinMaxRgb(out int min, out int max, int r, int g, int b)
{
if (r > g)
{
max = r;
min = g;
}
else
{
max = g;
min = r;
}
if (b > max)
{
max = b;
}
else if (b < min)
{
min = b;
}
}

/// <summary>
/// Gets the hue-saturation-lightness (HSL) lightness value for this System.Drawing.Color structure.
/// Gets the hue-saturation-lightness (HSL) lightness value for this <see cref="Color"/> structure.
/// </summary>
/// <returns>The lightness of this System.Drawing.Color. The lightness ranges from 0.0 through 1.0, where 0.0 represents black and 1.0 represents white.</returns>
/// <returns>
/// The lightness of this <see cref="Color"/>. The lightness ranges from 0.0 through 1.0, where 0.0 represents black and 1.0 represents white.
/// </returns>
public float GetBrightness()
{
float r = R / 255.0f;
float g = G / 255.0f;
float b = B / 255.0f;
float max = r > b ? r : b;
max = max > g ? max : g;
return max;
MinMaxRgb(out var min, out var max, R, G, B);

return (max + min) / (byte.MaxValue * 2f);
}

/// <summary>
Expand All @@ -1386,56 +1406,67 @@ public float GetBrightness()
public override int GetHashCode() => (int)_color;

/// <summary>
/// Gets the hue-saturation-lightness (HSL) hue value, in degrees, for this System.Drawing.Color structure.
/// Gets the hue-saturation-lightness (HSL) hue value, in degrees, for this <see cref="Color"/> structure.
/// </summary>
/// <returns>The hue, in degrees, of this System.Drawing.Color. The hue is measured in degrees,
/// ranging from 0.0 through 360.0, in HSL color space.</returns>
/// <returns>
/// The hue, in degrees, of this <see cref="Color"/>. The hue is measured in degrees, ranging from 0.0 through 360.0, in HSL color space.
/// </returns>
public float GetHue()
{
float r = R / 255.0f;
float g = G / 255.0f;
float b = B / 255.0f;
float max = r > b ? r : b;
max = max > g ? max : g;
float min = r > b ? b : r;
min = min > g ? g : min;

float h = 0.0f;
if (max == r && g >= b)
if (R == G && G == B)
{
h = (60 * (g - b)) / (max - min);
return 0f;
}
else if (max == r && g < b)

MinMaxRgb(out var min, out var max, R, G, B);

float delta = max - min;
float hue;

if (R == max)
{
hue = (G - B) / delta;
}
else if (G == max)
{
h = ((60 * (g - b)) / (max - min)) + 360;
hue = (B - R) / delta + 2f;
}
else if (max == g)
else
{
h = ((60 * (b - r)) / (max - min)) + 120;
hue = (R - G) / delta + 4f;
}
else if (max == b)

hue *= 60f;
if (hue < 0f)
{
h = ((60 * (r - g)) / (max - min)) + 240;
hue += 360f;
}

return h;
return hue;
}

/// <summary>
/// Gets the hue-saturation-lightness (HSL) saturation value for this System.Drawing.Color structure.
/// Gets the hue-saturation-lightness (HSL) saturation value for this <see cref="Color"/> structure.
/// </summary>
/// <returns>The saturation of this System.Drawing.Color. The saturation ranges from 0.0 through
/// 1.0, where 0.0 is grayscale and 1.0 is the most saturated.</returns>
/// <returns>
/// The saturation of this <see cref="Color"/>. The saturation ranges from 0.0 through 1.0, where 0.0 is grayscale and 1.0 is the most saturated.
/// </returns>
public float GetSaturation()
{
float r = R / 255.0f;
float g = G / 255.0f;
float b = B / 255.0f;
float max = r > b ? r : b;
max = max > g ? max : g;
float min = r > b ? b : r;
min = min > g ? g : min;
return (max == 0) ? 0.0f : (1.0f - (min / max));
if (R == G && G == B)
{
return 0f;
}

MinMaxRgb(out var min, out var max, R, G, B);

var div = max + min;
if (div > byte.MaxValue)
{
div = byte.MaxValue * 2 - max - min;
}

return (max - min) / (float)div;
}

/// <summary>
Expand Down

0 comments on commit 8f0ffd7

Please sign in to comment.