diff --git a/RGB.NET.Brushes/Brushes/SolidColorBrush.cs b/RGB.NET.Brushes/Brushes/SolidColorBrush.cs
index 6373d61..8e4a1a1 100644
--- a/RGB.NET.Brushes/Brushes/SolidColorBrush.cs
+++ b/RGB.NET.Brushes/Brushes/SolidColorBrush.cs
@@ -37,10 +37,7 @@ namespace RGB.NET.Brushes
#region Methods
///
- protected override Color GetColorAtPoint(Rectangle rectangle, BrushRenderTarget renderTarget)
- {
- return Color;
- }
+ protected override Color GetColorAtPoint(Rectangle rectangle, BrushRenderTarget renderTarget) => Color;
#endregion
@@ -50,19 +47,13 @@ namespace RGB.NET.Brushes
/// Converts a to a .
///
/// The to convert.
- public static explicit operator SolidColorBrush(Color color)
- {
- return new SolidColorBrush(color);
- }
+ public static explicit operator SolidColorBrush(Color color) => new SolidColorBrush(color);
///
/// Converts a to a .
///
/// The to convert.
- public static implicit operator Color(SolidColorBrush brush)
- {
- return brush.Color;
- }
+ public static implicit operator Color(SolidColorBrush brush) => brush.Color;
#endregion
}
diff --git a/RGB.NET.Brushes/Gradients/LinearGradient.cs b/RGB.NET.Brushes/Gradients/LinearGradient.cs
index 0b1dc38..8732262 100644
--- a/RGB.NET.Brushes/Gradients/LinearGradient.cs
+++ b/RGB.NET.Brushes/Gradients/LinearGradient.cs
@@ -53,7 +53,7 @@ namespace RGB.NET.Brushes.Gradients
public override Color GetColor(double offset)
{
if (GradientStops.Count == 0) return Color.Transparent;
- if (GradientStops.Count == 1) return new Color(GradientStops[0].Color);
+ if (GradientStops.Count == 1) return GradientStops[0].Color;
(GradientStop gsBefore, GradientStop gsAfter) = GetEnclosingGradientStops(offset, GradientStops, WrapGradient);
diff --git a/RGB.NET.Brushes/Gradients/RainbowGradient.cs b/RGB.NET.Brushes/Gradients/RainbowGradient.cs
index 0df739b..e565b24 100644
--- a/RGB.NET.Brushes/Gradients/RainbowGradient.cs
+++ b/RGB.NET.Brushes/Gradients/RainbowGradient.cs
@@ -56,7 +56,7 @@ namespace RGB.NET.Brushes.Gradients
double hue = (StartHue + (range * offset)) % 360f;
if (hue < 0)
hue += 360;
- return new Color(hue, 1f, 1f);
+ return Color.FromHSV(hue, 1, 1);
}
///
diff --git a/RGB.NET.Core/Brushes/AbstractBrush.cs b/RGB.NET.Core/Brushes/AbstractBrush.cs
index 0193913..716cc4a 100644
--- a/RGB.NET.Core/Brushes/AbstractBrush.cs
+++ b/RGB.NET.Core/Brushes/AbstractBrush.cs
@@ -64,8 +64,8 @@ namespace RGB.NET.Core
foreach (BrushRenderTarget renderTarget in renderTargets)
{
- Color color = new Color(GetColorAtPoint(rectangle, renderTarget)); // Clone the color, we don't want to have reference issues here and brushes might return the same color multiple times!}
- ApplyDecorators(rectangle, renderTarget, ref color);
+ Color color = GetColorAtPoint(rectangle, renderTarget);
+ color = ApplyDecorators(rectangle, renderTarget, color);
RenderedTargets[renderTarget] = color;
}
}
@@ -76,11 +76,13 @@ namespace RGB.NET.Core
/// The rectangle in which the brush should be drawn.
/// The target (key/point) from which the color should be taken.
/// The to be modified.
- protected virtual void ApplyDecorators(Rectangle rectangle, BrushRenderTarget renderTarget, ref Color color)
+ protected virtual Color ApplyDecorators(Rectangle rectangle, BrushRenderTarget renderTarget, Color color)
{
foreach (IBrushDecorator decorator in Decorators)
if (decorator.IsEnabled)
- decorator.ManipulateColor(rectangle, renderTarget, ref color);
+ color = decorator.ManipulateColor(rectangle, renderTarget, color);
+
+ return color;
}
///
@@ -88,7 +90,7 @@ namespace RGB.NET.Core
{
List renderTargets = RenderedTargets.Keys.ToList();
foreach (BrushRenderTarget renderTarget in renderTargets)
- FinalizeColor(RenderedTargets[renderTarget]); // Cloning here again shouldn't be needed since we did this above.
+ RenderedTargets[renderTarget] = FinalizeColor(RenderedTargets[renderTarget]);
}
///
@@ -102,20 +104,19 @@ namespace RGB.NET.Core
///
/// Finalizes the color by appliing the overall brightness and opacity.
/// This method should always be the last call of a implementation.
- /// If you overwrite this method please make sure that you never return the same color-object twice to prevent reference-issues!
///
/// The color to finalize.
/// The finalized color.
- protected virtual void FinalizeColor(Color color)
+ protected virtual Color FinalizeColor(Color color)
{
foreach (IColorCorrection colorCorrection in ColorCorrections)
- colorCorrection.ApplyTo(color);
+ color = colorCorrection.ApplyTo(color);
// Since we use HSV to calculate there is no way to make a color 'brighter' than 100%
// Be carefull with the naming: Since we use HSV the correct term is 'value' but outside we call it 'brightness'
// THIS IS NOT A HSB CALCULATION!!!
- color.Value *= Brightness <= 0 ? 0 : (Brightness >= 1.0 ? 1.0 : Brightness);
- color.A = (byte)(color.A * (Opacity <= 0 ? 0 : (Opacity >= 1.0 ? 1.0 : Opacity)));
+ return color.MultiplyValue(Brightness.Clamp(0, 1))
+ .MultiplyA(Opacity.Clamp(0, 1));
}
#endregion
diff --git a/RGB.NET.Core/ColorCorrection/IColorCorrection.cs b/RGB.NET.Core/ColorCorrection/IColorCorrection.cs
index 034ac9f..e3e417a 100644
--- a/RGB.NET.Core/ColorCorrection/IColorCorrection.cs
+++ b/RGB.NET.Core/ColorCorrection/IColorCorrection.cs
@@ -11,6 +11,6 @@ namespace RGB.NET.Core
/// Applies the to the given .
///
/// The to correct.
- void ApplyTo(Color color);
+ Color ApplyTo(Color color);
}
}
diff --git a/RGB.NET.Core/Decorators/IBrushDecorator.cs b/RGB.NET.Core/Decorators/IBrushDecorator.cs
index aef4f2c..812af24 100644
--- a/RGB.NET.Core/Decorators/IBrushDecorator.cs
+++ b/RGB.NET.Core/Decorators/IBrushDecorator.cs
@@ -12,6 +12,6 @@
/// The rectangle in which the should be drawn.
/// The target (key/point) from which the should be taken.
/// The to be modified.
- void ManipulateColor(Rectangle rectangle, BrushRenderTarget renderTarget, ref Color color);
+ Color ManipulateColor(Rectangle rectangle, BrushRenderTarget renderTarget, Color color);
}
}
diff --git a/RGB.NET.Core/Extensions/DoubleExtensions.cs b/RGB.NET.Core/Extensions/DoubleExtensions.cs
deleted file mode 100644
index 964a205..0000000
--- a/RGB.NET.Core/Extensions/DoubleExtensions.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using System;
-using System.Runtime.CompilerServices;
-
-namespace RGB.NET.Core
-{
- ///
- /// Offers some extensions and helper-methods for the work with doubles
- ///
- public static class DoubleExtensions
- {
- #region Constants
-
- ///
- /// Defines the precision RGB.NET processes floating point comparisons in.
- ///
- public const double TOLERANCE = 1E-10;
-
- #endregion
-
- #region Methods
-
- ///
- /// Checks if two values are equal respecting the .
- ///
- /// The first value to compare.
- /// The first value to compare.
- /// true if the difference is smaller than the ; otherwise, false.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static bool EqualsInTolerance(this double value1, double value2)
- {
- return Math.Abs(value1 - value2) < TOLERANCE;
- }
-
- ///
- /// Camps the provided value to be bigger or equal min and smaller or equal max.
- ///
- /// The value to clamp.
- /// The lower value of the range the value is clamped to.
- /// The higher value of the range the value is clamped to.
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double Clamp(this double value, double min, double max)
- {
- return Math.Max(min, Math.Min(max, value));
- }
-
- #endregion
- }
-}
diff --git a/RGB.NET.Core/Extensions/MathExtensions.cs b/RGB.NET.Core/Extensions/MathExtensions.cs
new file mode 100644
index 0000000..34b92d8
--- /dev/null
+++ b/RGB.NET.Core/Extensions/MathExtensions.cs
@@ -0,0 +1,87 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace RGB.NET.Core
+{
+ ///
+ /// Offers some extensions and helper-methods for the work with doubles
+ ///
+ public static class DoubleExtensions
+ {
+ #region Constants
+
+ ///
+ /// Defines the precision RGB.NET processes floating point comparisons in.
+ ///
+ public const double TOLERANCE = 1E-10;
+
+ #endregion
+
+ #region Methods
+
+ ///
+ /// Checks if two values are equal respecting the .
+ ///
+ /// The first value to compare.
+ /// The first value to compare.
+ /// true if the difference is smaller than the ; otherwise, false.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool EqualsInTolerance(this double value1, double value2) => Math.Abs(value1 - value2) < TOLERANCE;
+
+ ///
+ /// Clamps the provided value to be bigger or equal min and smaller or equal max.
+ ///
+ /// The value to clamp.
+ /// The lower value of the range the value is clamped to.
+ /// The higher value of the range the value is clamped to.
+ /// The clamped value.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Clamp(this double value, double min, double max) => Math.Max(min, Math.Min(max, value));
+
+ ///
+ /// Clamps the provided value to be bigger or equal min and smaller or equal max.
+ ///
+ /// The value to clamp.
+ /// The lower value of the range the value is clamped to.
+ /// The higher value of the range the value is clamped to.
+ /// The clamped value.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int Clamp(this int value, int min, int max) => Math.Max(min, Math.Min(max, value));
+
+ ///
+ /// Enforces the provided value to be in the specified range by wrapping it around the edges if it exceeds them.
+ ///
+ /// The value to wrap.
+ /// The lower value of the range the value is wrapped into.
+ /// The higher value of the range the value is wrapped into.
+ /// The wrapped value.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Wrap(this double value, double min, double max)
+ {
+ double range = max - min;
+
+ while (value > max)
+ value -= range;
+
+ while (value < min)
+ value += range;
+
+ return value;
+ }
+
+ #region Internal
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal static byte GetByteValueFromPercentage(this double percentage)
+ {
+ if (double.IsNaN(percentage)) return 0;
+
+ percentage = percentage.Clamp(0, 1.0);
+ return (byte)(percentage.Equals(1.0) ? 255 : percentage * 256.0);
+ }
+
+ #endregion
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Core/Leds/Color.cs b/RGB.NET.Core/Leds/Color.cs
index c7391ac..65786b0 100644
--- a/RGB.NET.Core/Leds/Color.cs
+++ b/RGB.NET.Core/Leds/Color.cs
@@ -1,5 +1,6 @@
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedMember.Global
+// ReSharper disable UnusedMethodReturnValue.Global
using System;
using System.Diagnostics;
@@ -11,14 +12,14 @@ namespace RGB.NET.Core
/// Represents an ARGB (alpha, red, green, blue) color.
///
[DebuggerDisplay("[A: {A}, R: {R}, G: {G}, B: {B}, H: {Hue}, S: {Saturation}, V: {Value}]")]
- public class Color : AbstractBindable
+ public struct Color
{
#region Constants
///
/// Gets an transparent color [A: 0, R: 0, G: 0, B: 0]
///
- public static Color Transparent => new Color();
+ public static Color Transparent => new Color(0, 0, 0, 0);
#endregion
@@ -26,158 +27,64 @@ namespace RGB.NET.Core
#region RGB
- private byte _a;
///
- /// Gets or sets the alpha component value of this as byte in the range [0..255].
+ /// Gets the alpha component value of this as byte in the range [0..255].
///
- public byte A
- {
- get => _a;
- set
- {
- if (SetProperty(ref _a, value))
- // ReSharper disable once ExplicitCallerInfoArgument
- OnPropertyChanged(nameof(APercent));
- }
- }
+ public byte A { get; }
///
- /// Gets or sets the alpha component value of this as percentage in the range [0..1].
+ /// Gets the alpha component value of this as percentage in the range [0..1].
///
- public double APercent
- {
- get => A / (double)byte.MaxValue;
- set => A = GetByteValueFromPercentage(value);
- }
-
- private byte _r;
- ///
- /// Gets or sets the red component value of this as byte in the range [0..255].
- ///
- public byte R
- {
- get => _r;
- set
- {
- if (SetProperty(ref _r, value))
- {
- InvalidateHSV();
- // ReSharper disable once ExplicitCallerInfoArgument
- OnPropertyChanged(nameof(RPercent));
- }
- }
- }
+ public double APercent => A / (double)byte.MaxValue;
///
- /// Gets or sets the red component value of this as percentage in the range [0..1].
+ /// Gets the red component value of this as byte in the range [0..255].
///
- public double RPercent
- {
- get => R / (double)byte.MaxValue;
- set => R = GetByteValueFromPercentage(value);
- }
-
- private byte _g;
- ///
- /// Gets or sets the green component value of this as byte in the range [0..255].
- ///
- public byte G
- {
- get => _g;
- set
- {
- if (SetProperty(ref _g, value))
- {
- InvalidateHSV();
- // ReSharper disable ExplicitCallerInfoArgument
- OnPropertyChanged(nameof(GPercent));
- // ReSharper restore ExplicitCallerInfoArgument
- }
- }
- }
+ public byte R { get; }
///
- /// Gets or sets the green component value of this as percentage in the range [0..1].
+ /// Gets the red component value of this as percentage in the range [0..1].
///
- public double GPercent
- {
- get => G / (double)byte.MaxValue;
- set => G = GetByteValueFromPercentage(value);
- }
-
- private byte _b;
- ///
- /// Gets or sets the blue component value of this as byte in the range [0..255].
- ///
- public byte B
- {
- get => _b;
- set
- {
- if (SetProperty(ref _b, value))
- {
- InvalidateHSV();
- // ReSharper disable ExplicitCallerInfoArgument
- OnPropertyChanged(nameof(BPercent));
- // ReSharper restore ExplicitCallerInfoArgument
- }
- }
- }
+ public double RPercent => R / (double)byte.MaxValue;
///
- /// Gets or sets the blue component value of this as percentage in the range [0..1].
+ /// Gets the green component value of this as byte in the range [0..255].
///
- public double BPercent
- {
- get => B / (double)byte.MaxValue;
- set => B = GetByteValueFromPercentage(value);
- }
+ public byte G { get; }
+
+ ///
+ /// Gets the green component value of this as percentage in the range [0..1].
+ ///
+ public double GPercent => G / (double)byte.MaxValue;
+
+ ///
+ /// Gets the blue component value of this as byte in the range [0..255].
+ ///
+ public byte B { get; }
+
+ ///
+ /// Gets the blue component value of this as percentage in the range [0..1].
+ ///
+ public double BPercent => B / (double)byte.MaxValue;
#endregion
#region HSV
- private double? _hue;
///
- /// Gets or sets the hue component value (HSV-color space) of this as degree in the range [0..360].
+ /// Gets the hue component value (HSV-color space) of this as degree in the range [0..360].
///
- public double Hue
- {
- get => _hue ?? (_hue = CaclulateHueFromRGB()).Value;
- set
- {
- if (SetProperty(ref _hue, value))
- UpdateRGBFromHSV();
- }
- }
+ public double Hue { get; }
- private double? _saturation;
///
- /// Gets or sets the saturation component value (HSV-color space) of this as degree in the range [0..1].
+ /// Gets the saturation component value (HSV-color space) of this as degree in the range [0..1].
///
- public double Saturation
- {
- get => _saturation ?? (_saturation = CaclulateSaturationFromRGB()).Value;
- set
- {
- if (SetProperty(ref _saturation, value))
- UpdateRGBFromHSV();
- }
- }
+ public double Saturation { get; }
- private double? _value;
///
- /// Gets or sets the value component value (HSV-color space) of this as degree in the range [0..1].
+ /// Gets the value component value (HSV-color space) of this as degree in the range [0..1].
///
- public double Value
- {
- get => _value ?? (_value = CaclulateValueFromRGB()).Value;
- set
- {
- if (SetProperty(ref _value, value))
- UpdateRGBFromHSV();
- }
- }
+ public double Value { get; }
#endregion
@@ -187,27 +94,30 @@ namespace RGB.NET.Core
///
///
- /// Initializes a new instance of the class.
- /// The class created by this constructor equals .
- ///
- public Color()
- : this(0, 0, 0, 0)
- { }
-
- ///
- ///
- /// Initializes a new instance of the class using only RGB-Values.
+ /// Initializes a new instance of the struct using RGB-Values.
/// Alpha defaults to 255.
///
/// The red component value of this .
/// The green component value of this .
/// The blue component value of this .
public Color(byte r, byte g, byte b)
- : this(255, r, g, b)
+ : this(byte.MaxValue, r, g, b)
+ { }
+
+ ///
+ ///
+ /// Initializes a new instance of the struct using RGB-Values.
+ /// Alpha defaults to 255.
+ ///
+ /// The red component value of this .
+ /// The green component value of this .
+ /// The blue component value of this .
+ public Color(int r, int g, int b)
+ : this((byte)r.Clamp(0, byte.MaxValue), (byte)g.Clamp(0, byte.MaxValue), (byte)b.Clamp(0, byte.MaxValue))
{ }
///
- /// Initializes a new instance of the class using ARGB-values.
+ /// Initializes a new instance of the struct using ARGB values.
///
/// The alpha component value of this .
/// The red component value of this .
@@ -219,218 +129,172 @@ namespace RGB.NET.Core
this.R = r;
this.G = g;
this.B = b;
+
+ (double h, double s, double v) = CaclulateHSVFromRGB(r, g, b);
+ Hue = h;
+ Saturation = s;
+ Value = v;
}
- ///
///
- /// Initializes a new instance of the class using only RGB-Values.
- /// Alpha defaults to 255.
+ /// Initializes a new instance of the struct using ARGB values.
///
- /// The hue component value of this .
- /// The saturation component value of this .
- /// The value component value of this .
- public Color(double hue, double saturation, double value)
- : this(255, hue, saturation, value)
+ /// The alpha component value of this .
+ /// The red component value of this .
+ /// The green component value of this .
+ /// The blue component value of this .
+ public Color(int a, int r, int g, int b)
+ : this((byte)a.Clamp(0, byte.MaxValue), (byte)r.Clamp(0, byte.MaxValue), (byte)g.Clamp(0, byte.MaxValue), (byte)b.Clamp(0, byte.MaxValue))
{ }
///
- /// Initializes a new instance of the class using ARGB-values.
+ /// Initializes a new instance of the struct using RGB-percent values.
+ ///
+ /// The red component value of this .
+ /// The green component value of this .
+ /// The blue component value of this .
+ public Color(double r, double g, double b)
+ : this(byte.MaxValue,
+ r.GetByteValueFromPercentage(),
+ g.GetByteValueFromPercentage(),
+ b.GetByteValueFromPercentage())
+ { }
+
+ ///
+ /// Initializes a new instance of the struct using ARGB-percent values.
///
/// The alpha component value of this .
- /// The hue component value of this .
- /// The saturation component value of this .
- /// The value component value of this .
- public Color(byte a, double hue, double saturation, double value)
- {
- this.A = a;
- this._hue = hue;
- this._saturation = saturation;
- this._value = value;
-
- // ReSharper disable ExplicitCallerInfoArgument
- // ReSharper disable VirtualMemberCallInConstructor
- OnPropertyChanged(nameof(Hue));
- OnPropertyChanged(nameof(Saturation));
- OnPropertyChanged(nameof(Value));
- // ReSharper restore VirtualMemberCallInConstructor
- // ReSharper restore ExplicitCallerInfoArgument
-
- UpdateRGBFromHSV();
- }
+ /// The red component value of this .
+ /// The green component value of this .
+ /// The blue component value of this .
+ public Color(double a, double r, double g, double b)
+ : this(a.GetByteValueFromPercentage(),
+ r.GetByteValueFromPercentage(),
+ g.GetByteValueFromPercentage(),
+ b.GetByteValueFromPercentage())
+ { }
///
///
- /// Initializes a new instance of the class by cloning a existing .
+ /// Initializes a new instance of the struct by cloning a existing .
///
/// The the values are copied from.
public Color(Color color)
- : this(color.A, color.R, color.G, color.B)
- { }
+ : this(color.A, color.R, color.G, color.B) { }
#endregion
#region Methods
+ #region Factory
+
///
- /// Blends a over this color.
+ /// Creates a new instance of the struct using HSV-Values.
///
- /// The to blend.
- public void Blend(Color color)
+ /// The hue component value of this .
+ /// The saturation component value of this .
+ /// The value component value of this .
+ /// The color created from the values.
+ public static Color FromHSV(double hue, double saturation, double value)
{
- if (color.A == 0) return;
-
- // ReSharper disable once ConvertIfStatementToSwitchStatement
- if (color.A == 255)
- {
- A = color.A;
- R = color.R;
- G = color.G;
- B = color.B;
- }
- else
- {
- double resultA = (1.0 - ((1.0 - color.APercent) * (1.0 - APercent)));
- double resultR = (((color.RPercent * color.APercent) / resultA) + ((RPercent * APercent * (1.0 - color.APercent)) / resultA));
- double resultG = (((color.GPercent * color.APercent) / resultA) + ((GPercent * APercent * (1.0 - color.APercent)) / resultA));
- double resultB = (((color.BPercent * color.APercent) / resultA) + ((BPercent * APercent * (1.0 - color.APercent)) / resultA));
-
- APercent = resultA;
- RPercent = resultR;
- GPercent = resultG;
- BPercent = resultB;
- }
+ (byte r, byte g, byte b) = CalculateRGBFromHSV(hue, saturation, value);
+ return new Color(r, g, b);
}
- private void InvalidateHSV()
+ ///
+ /// Creates a new instance of the struct using AHSV-Values.
+ ///
+ /// The alpha component value of this .
+ /// The hue component value of this .
+ /// The saturation component value of this .
+ /// The value component value of this .
+ /// The color created from the values.
+ public static Color FromHSV(int a, double hue, double saturation, double value)
{
- _hue = null;
- _saturation = null;
- _value = null;
-
- // ReSharper disable ExplicitCallerInfoArgument
- OnPropertyChanged(nameof(Hue));
- OnPropertyChanged(nameof(Saturation));
- OnPropertyChanged(nameof(Value));
- // ReSharper restore ExplicitCallerInfoArgument
+ (byte r, byte g, byte b) = CalculateRGBFromHSV(hue, saturation, value);
+ return new Color(a, r, g, b);
}
- private double CaclulateHueFromRGB()
- {
- if ((R == G) && (G == B)) return 0.0;
+ #endregion
- double min = Math.Min(Math.Min(R, G), B);
- double max = Math.Max(Math.Max(R, G), B);
+ private static (double h, double s, double v) CaclulateHSVFromRGB(byte r, byte g, byte b)
+ {
+ if ((r == g) && (g == b)) return (0, 0, 0);
+
+ int min = Math.Min(Math.Min(r, g), b);
+ int max = Math.Max(Math.Max(r, g), b);
double hue;
- if (max.EqualsInTolerance(R)) // r is max
- hue = (G - B) / (max - min);
- else if (max.EqualsInTolerance(G)) // g is max
- hue = 2.0 + ((B - R) / (max - min));
+ if (max == r) // r is max
+ hue = (g - b) / (double)(max - min);
+ else if (max == g) // g is max
+ hue = 2.0 + ((b - r) / (double)(max - min));
else // b is max
- hue = 4.0 + ((R - G) / (max - min));
+ hue = 4.0 + ((r - g) / (double)(max - min));
hue = hue * 60.0;
if (hue < 0.0)
hue += 360.0;
- return hue;
+ double saturation = (max == 0) ? 0 : 1.0 - (min / (double)max);
+ double value = Math.Max(r, Math.Max(g, b)) / 255.0;
+
+ return (hue, saturation, value);
}
- private double CaclulateSaturationFromRGB()
+ private static (byte r, byte g, byte b) CalculateRGBFromHSV(double h, double s, double v)
{
- int max = Math.Max(R, Math.Max(G, B));
- int min = Math.Min(R, Math.Min(G, B));
+ h = h.Wrap(0, 360);
+ s = s.Clamp(0, 1);
+ v = v.Clamp(0, 1);
- return (max == 0) ? 0 : 1.0 - (min / (double)max);
- }
-
- private double CaclulateValueFromRGB()
- {
- return Math.Max(R, Math.Max(G, B)) / 255.0;
- }
-
- private void UpdateRGBFromHSV()
- {
- if (Saturation <= 0.0)
+ if (s <= 0.0)
{
- byte val = GetByteValueFromPercentage(Value);
- UpdateRGBWithoutInvalidatingHSV(val, val, val);
+ byte val = v.GetByteValueFromPercentage();
+ return (val, val, val);
}
- double hh = (Hue % 360.0) / 60.0;
+ double hh = h / 60.0;
int i = (int)hh;
double ff = hh - i;
- double p = Value * (1.0 - Saturation);
- double q = Value * (1.0 - (Saturation * ff));
- double t = Value * (1.0 - (Saturation * (1.0 - ff)));
+ double p = v * (1.0 - s);
+ double q = v * (1.0 - (s * ff));
+ double t = v * (1.0 - (s * (1.0 - ff)));
switch (i)
{
case 0:
- UpdateRGBWithoutInvalidatingHSV(GetByteValueFromPercentage(Value),
- GetByteValueFromPercentage(t),
- GetByteValueFromPercentage(p));
- break;
+ return (v.GetByteValueFromPercentage(),
+ t.GetByteValueFromPercentage(),
+ p.GetByteValueFromPercentage());
case 1:
- UpdateRGBWithoutInvalidatingHSV(GetByteValueFromPercentage(q),
- GetByteValueFromPercentage(Value),
- GetByteValueFromPercentage(p));
- break;
+ return (q.GetByteValueFromPercentage(),
+ v.GetByteValueFromPercentage(),
+ p.GetByteValueFromPercentage());
case 2:
- UpdateRGBWithoutInvalidatingHSV(GetByteValueFromPercentage(p),
- GetByteValueFromPercentage(Value),
- GetByteValueFromPercentage(t));
- break;
+ return (p.GetByteValueFromPercentage(),
+ v.GetByteValueFromPercentage(),
+ t.GetByteValueFromPercentage());
case 3:
- UpdateRGBWithoutInvalidatingHSV(GetByteValueFromPercentage(p),
- GetByteValueFromPercentage(q),
- GetByteValueFromPercentage(Value));
- break;
+ return (p.GetByteValueFromPercentage(),
+ q.GetByteValueFromPercentage(),
+ v.GetByteValueFromPercentage());
case 4:
- UpdateRGBWithoutInvalidatingHSV(GetByteValueFromPercentage(t),
- GetByteValueFromPercentage(p),
- GetByteValueFromPercentage(Value));
- break;
+ return (t.GetByteValueFromPercentage(),
+ p.GetByteValueFromPercentage(),
+ v.GetByteValueFromPercentage());
default:
- UpdateRGBWithoutInvalidatingHSV(GetByteValueFromPercentage(Value),
- GetByteValueFromPercentage(p),
- GetByteValueFromPercentage(q));
- break;
+ return (v.GetByteValueFromPercentage(),
+ p.GetByteValueFromPercentage(),
+ q.GetByteValueFromPercentage());
}
}
- private void UpdateRGBWithoutInvalidatingHSV(byte r, byte g, byte b)
- {
- _r = r;
- _g = g;
- _b = b;
-
- // ReSharper disable ExplicitCallerInfoArgument
- OnPropertyChanged(nameof(R));
- OnPropertyChanged(nameof(RPercent));
- OnPropertyChanged(nameof(G));
- OnPropertyChanged(nameof(GPercent));
- OnPropertyChanged(nameof(B));
- OnPropertyChanged(nameof(BPercent));
- // ReSharper enable ExplicitCallerInfoArgument
- }
-
- private static byte GetByteValueFromPercentage(double percentage)
- {
- if (double.IsNaN(percentage)) return 0;
-
- percentage = percentage.Clamp(0, 1.0);
- return (byte)(percentage.Equals(1.0) ? 255 : percentage * 256.0);
- }
-
///
- /// Converts the individual byte-values of this to a human-readable string.
+ /// Converts the individual byte values of this to a human-readable string.
///
- /// A string that contains the individual byte-values of this . For example "[A: 255, R: 255, G: 0, B: 0]".
- public override string ToString()
- {
- return $"[A: {A}, R: {R}, G: {G}, B: {B}, H: {Hue}, S: {Saturation}, V: {Value}]";
- }
+ /// A string that contains the individual byte values of this . For example "[A: 255, R: 255, G: 0, B: 0]".
+ public override string ToString() => $"[A: {A}, R: {R}, G: {G}, B: {B}, H: {Hue}, S: {Saturation}, V: {Value}]";
///
/// Tests whether the specified object is a and is equivalent to this .
@@ -439,16 +303,9 @@ namespace RGB.NET.Core
/// true if is a equivalent to this ; otherwise, false.
public override bool Equals(object obj)
{
- Color compareColor = obj as Color;
- if (ReferenceEquals(compareColor, null))
- return false;
-
- if (ReferenceEquals(this, compareColor))
- return true;
-
- if (GetType() != compareColor.GetType())
- return false;
+ if (!(obj is Color)) return false;
+ Color compareColor = (Color)obj;
return (compareColor.A == A) && (compareColor.R == R) && (compareColor.G == G) && (compareColor.B == B);
}
@@ -468,20 +325,741 @@ namespace RGB.NET.Core
}
}
+ #region Deconstruction
+
+ ///
+ /// Deconstructs the Color into it's components.
+ ///
+ /// The alpha component of this color.
+ /// The red component of this color.
+ /// The green component of this color.
+ /// The blue component of this color.
+ /// The hue component of this color.
+ /// The saturation component of this color.
+ /// The value component of this color.
+ public void Deconstruct(out byte a, out byte r, out byte g, out byte b, out double hue, out double saturation, out double value)
+ {
+ Deconstruct(out a, out r, out g, out b);
+ Deconstruct(out hue, out saturation, out value);
+ }
+
+ ///
+ /// Deconstructs the Color into it's ARGB-components.
+ ///
+ /// The alpha component of this color.
+ /// The red component of this color.
+ /// The green component of this color.
+ /// The blue component of this color.
+ public void Deconstruct(out byte a, out byte r, out byte g, out byte b)
+ {
+ a = A;
+ r = R;
+ g = G;
+ b = B;
+ }
+
+ ///
+ /// Deconstructs the Color into it's HSV-components.
+ ///
+ /// The hue component of this color.
+ /// The saturation component of this color.
+ /// The value component of this color.
+ public void Deconstruct(out double hue, out double saturation, out double value)
+ {
+ hue = Hue;
+ saturation = Saturation;
+ value = Value;
+ }
+
+ #endregion
+
+ #region Manipulation
+
+ ///
+ /// Blends a over this color.
+ ///
+ /// The to blend.
+ public Color Blend(Color color)
+ {
+ if (color.A == 0) return this;
+
+ if (color.A == 255)
+ return color;
+
+ double resultA = (1.0 - ((1.0 - color.APercent) * (1.0 - APercent)));
+ double resultR = (((color.RPercent * color.APercent) / resultA) + ((RPercent * APercent * (1.0 - color.APercent)) / resultA));
+ double resultG = (((color.GPercent * color.APercent) / resultA) + ((GPercent * APercent * (1.0 - color.APercent)) / resultA));
+ double resultB = (((color.BPercent * color.APercent) / resultA) + ((BPercent * APercent * (1.0 - color.APercent)) / resultA));
+
+ return new Color(resultA, resultR, resultG, resultB);
+ }
+
+ #region Add
+
+ ///
+ /// Adds the given RGB values to this color.
+ ///
+ /// The red value to add.
+ /// The green value to add.
+ /// The blue value to add.
+ /// The new color after the modification.
+ public Color AddRGB(int r, int g, int b) => AddRGB(0, r, g, b);
+
+ ///
+ /// Adds the given RGB values to this color.
+ ///
+ /// The alpha value to add.
+ /// The red value to add.
+ /// The green value to add.
+ /// The blue value to add.
+ /// The new color after the modification.
+ public Color AddRGB(int a, int r, int g, int b)
+ => new Color(A + a, R + r, G + g, B + b);
+
+ ///
+ /// Adds the given RGB-percent values to this color.
+ ///
+ /// The red value to add.
+ /// The green value to add.
+ /// The blue value to add.
+ /// The new color after the modification.
+ public Color AddPercent(double rPercent, double gPercent, double bPercent) => AddPercent(0, rPercent, gPercent, bPercent);
+
+ ///
+ /// Adds the given RGB-percent values to this color.
+ ///
+ /// The alpha value to add.
+ /// The red value to add.
+ /// The green value to add.
+ /// The blue value to add.
+ /// The new color after the modification.
+ public Color AddPercent(double aPercent, double rPercent, double gPercent, double bPercent)
+ => new Color(APercent + aPercent, RPercent + rPercent, GPercent + gPercent, BPercent + bPercent);
+
+ ///
+ /// Adds the given HSV values to this color.
+ ///
+ /// The hue value to add.
+ /// The saturation value to add.
+ /// The value value to add.
+ /// The new color after the modification.
+ public Color AddHSV(double hue, double saturation, double value) => AddHSV(0, hue, saturation, value);
+
+ ///
+ /// Adds the given HSV values to this color.
+ ///
+ /// The alpha value to add.
+ /// The hue value to add.
+ /// The saturation value to add.
+ /// The value value to add.
+ /// The new color after the modification.
+ public Color AddHSV(int a, double hue, double saturation, double value)
+ => Color.FromHSV(A + a, Hue + hue, Saturation + saturation, Value + value);
+
+ ///
+ /// Adds the given alpha value to this color.
+ ///
+ /// The alpha value to add.
+ /// The new color after the modification.
+ public Color AddA(int a) => new Color(A + a, R, G, B);
+
+ ///
+ /// Adds the given alpha-percent value to this color.
+ ///
+ /// The alpha value to add.
+ /// The new color after the modification.
+ public Color AddAPercent(double aPercent) => new Color(APercent + aPercent, RPercent, GPercent, BPercent);
+
+ ///
+ /// Adds the given red value to this color.
+ ///
+ /// The red value to add.
+ /// The new color after the modification.
+ public Color AddR(int r) => new Color(A, R + r, G, B);
+
+ ///
+ /// Adds the given red-percent value to this color.
+ ///
+ /// The red value to add.
+ /// The new color after the modification.
+ public Color AddRPercent(double rPercent) => new Color(APercent, RPercent + rPercent, GPercent, BPercent);
+
+ ///
+ /// Adds the given green value to this color.
+ ///
+ /// The green value to add.
+ /// The new color after the modification.
+ public Color AddG(int g) => new Color(A, R, G + g, B);
+
+ ///
+ /// Adds the given green-percent value to this color.
+ ///
+ /// The green value to add.
+ /// The new color after the modification.
+ public Color AddGPercent(double gPercent) => new Color(APercent, RPercent, GPercent + gPercent, BPercent);
+
+ ///
+ /// Adds the given blue value to this color.
+ ///
+ /// The blue value to add.
+ /// The new color after the modification.
+ public Color AddB(int b) => new Color(A, R, G, B + b);
+
+ ///
+ /// Adds the given blue-percent value to this color.
+ ///
+ /// The blue value to add.
+ /// The new color after the modification.
+ public Color AddBPercent(double bPercent) => new Color(APercent, RPercent, GPercent, BPercent + bPercent);
+
+ ///
+ /// Adds the given hue value to this color.
+ ///
+ /// The hue value to add.
+ /// The new color after the modification.
+ public Color AddHue(double hue) => FromHSV(A, Hue + hue, Saturation, Value);
+
+ ///
+ /// Adds the given saturation value to this color.
+ ///
+ /// The saturation value to add.
+ /// The new color after the modification.
+ public Color AddSaturation(double saturation) => FromHSV(A, Hue, Saturation + saturation, Value);
+
+ ///
+ /// Adds the given value value to this color.
+ ///
+ /// The value value to add.
+ /// The new color after the modification.
+ public Color AddValue(double value) => FromHSV(A, Hue, Saturation, Value + value);
+
+ #endregion
+
+ #region Subtract
+
+ ///
+ /// Subtracts the given RGB values to this color.
+ ///
+ /// The red value to subtract.
+ /// The green value to subtract.
+ /// The blue value to subtract.
+ /// The new color after the modification.
+ public Color SubtractRGB(int r, int g, int b) => SubtractRGB(0, r, g, b);
+
+ ///
+ /// Subtracts the given RGB values to this color.
+ ///
+ /// The alpha value to subtract.
+ /// The red value to subtract.
+ /// The green value to subtract.
+ /// The blue value to subtract.
+ /// The new color after the modification.
+ public Color SubtractRGB(int a, int r, int g, int b)
+ => new Color(A - a, R - r, G - g, B - b);
+
+ ///
+ /// Subtracts the given RGB-percent values to this color.
+ ///
+ /// The red value to subtract.
+ /// The green value to subtract.
+ /// The blue value to subtract.
+ /// The new color after the modification.
+ public Color SubtractPercent(double rPercent, double gPercent, double bPercent) => SubtractPercent(0, rPercent, gPercent, bPercent);
+
+ ///
+ /// Subtracts the given RGB-percent values to this color.
+ ///
+ /// The alpha value to subtract.
+ /// The red value to subtract.
+ /// The green value to subtract.
+ /// The blue value to subtract.
+ /// The new color after the modification.
+ public Color SubtractPercent(double aPercent, double rPercent, double gPercent, double bPercent)
+ => new Color(APercent - aPercent, RPercent - rPercent, GPercent - gPercent, BPercent - bPercent);
+
+ ///
+ /// Subtracts the given HSV values to this color.
+ ///
+ /// The hue value to subtract.
+ /// The saturation value to subtract.
+ /// The value value to subtract.
+ /// The new color after the modification.
+ public Color SubtractHSV(double hue, double saturation, double value) => SubtractHSV(0, hue, saturation, value);
+
+ ///
+ /// Subtracts the given HSV values to this color.
+ ///
+ /// The alpha value to subtract.
+ /// The hue value to subtract.
+ /// The saturation value to subtract.
+ /// The value value to subtract.
+ /// The new color after the modification.
+ public Color SubtractHSV(int a, double hue, double saturation, double value)
+ => FromHSV(A - a, Hue - hue, Saturation - saturation, Value - value);
+
+ ///
+ /// Subtracts the given alpha value to this color.
+ ///
+ /// The alpha value to subtract.
+ /// The new color after the modification.
+ public Color SubtractA(int a) => new Color(A - a, R, G, B);
+
+ ///
+ /// Subtracts the given alpha-percent value to this color.
+ ///
+ /// The alpha value to subtract.
+ /// The new color after the modification.
+ public Color SubtractAPercent(double aPercent) => new Color(APercent - aPercent, RPercent, GPercent, BPercent);
+
+ ///
+ /// Subtracts the given red value to this color.
+ ///
+ /// The red value to subtract.
+ /// The new color after the modification.
+ public Color SubtractR(int r) => new Color(A, R - r, G, B);
+
+ ///
+ /// Subtracts the given red-percent value to this color.
+ ///
+ /// The red value to subtract.
+ /// The new color after the modification.
+ public Color SubtractRPercent(double rPercent) => new Color(APercent, RPercent - rPercent, GPercent, BPercent);
+
+ ///
+ /// Subtracts the given green value to this color.
+ ///
+ /// The green value to subtract.
+ /// The new color after the modification.
+ public Color SubtractG(int g) => new Color(A, R, G - g, B);
+
+ ///
+ /// Subtracts the given green-percent value to this color.
+ ///
+ /// The green value to subtract.
+ /// The new color after the modification.
+ public Color SubtractGPercent(double gPercent) => new Color(APercent, RPercent, GPercent - gPercent, BPercent);
+
+ ///
+ /// Subtracts the given blue value to this color.
+ ///
+ /// The blue value to subtract.
+ /// The new color after the modification.
+ public Color SubtractB(int b) => new Color(A, R, G, B - b);
+
+ ///
+ /// Subtracts the given blue-percent value to this color.
+ ///
+ /// The blue value to subtract.
+ /// The new color after the modification.
+ public Color SubtractBPercent(double bPercent) => new Color(APercent, RPercent, GPercent, BPercent - bPercent);
+
+ ///
+ /// Subtracts the given hue value to this color.
+ ///
+ /// The hue value to subtract.
+ /// The new color after the modification.
+ public Color SubtractHue(double hue) => FromHSV(A, Hue - hue, Saturation, Value);
+
+ ///
+ /// Subtracts the given saturation value to this color.
+ ///
+ /// The saturation value to subtract.
+ /// The new color after the modification.
+ public Color SubtractSaturation(double saturation) => FromHSV(A, Hue, Saturation - saturation, Value);
+
+ ///
+ /// Subtracts the given value value to this color.
+ ///
+ /// The value value to subtract.
+ /// The new color after the modification.
+ public Color SubtractValue(double value) => FromHSV(A, Hue, Saturation, Value - value);
+
+ #endregion
+
+ #region Multiply
+
+ ///
+ /// Multiplies the given RGB values to this color.
+ ///
+ /// The red value to multiply.
+ /// The green value to multiply.
+ /// The blue value to multiply.
+ /// The new color after the modification.
+ public Color MultiplyRGB(double r, double g, double b) => MultiplyRGB(1, r, g, b);
+
+ ///
+ /// Multiplies the given RGB values to this color.
+ ///
+ /// The alpha value to multiply.
+ /// The red value to multiply.
+ /// The green value to multiply.
+ /// The blue value to multiply.
+ /// The new color after the modification.
+ public Color MultiplyRGB(double a, double r, double g, double b)
+ => new Color((int)Math.Round(A * a), (int)Math.Round(R * r), (int)Math.Round(G * g), (int)Math.Round(B * b));
+
+ ///
+ /// Multiplies the given RGB-percent values to this color.
+ ///
+ /// The red value to multiply.
+ /// The green value to multiply.
+ /// The blue value to multiply.
+ /// The new color after the modification.
+ public Color MultiplyPercent(double rPercent, double gPercent, double bPercent) => MultiplyPercent(1, rPercent, gPercent, bPercent);
+
+ ///
+ /// Multiplies the given RGB-percent values to this color.
+ ///
+ /// The alpha value to multiply.
+ /// The red value to multiply.
+ /// The green value to multiply.
+ /// The blue value to multiply.
+ /// The new color after the modification.
+ public Color MultiplyPercent(double aPercent, double rPercent, double gPercent, double bPercent)
+ => new Color(APercent * aPercent, RPercent * rPercent, GPercent * gPercent, BPercent * bPercent);
+
+ ///
+ /// Multiplies the given HSV values to this color.
+ ///
+ /// The hue value to multiply.
+ /// The saturation value to multiply.
+ /// The value value to multiply.
+ /// The new color after the modification.
+ public Color MultiplyHSV(double hue, double saturation, double value) => MultiplyHSV(1, hue, saturation, value);
+
+ ///
+ /// Multiplies the given HSV values to this color.
+ ///
+ /// The alpha value to multiply.
+ /// The hue value to multiply.
+ /// The saturation value to multiply.
+ /// The value value to multiply.
+ /// The new color after the modification.
+ public Color MultiplyHSV(double a, double hue, double saturation, double value)
+ => FromHSV((int)Math.Round(A * a), Hue * hue, Saturation * saturation, Value * value);
+
+ ///
+ /// Multiplies the given alpha value to this color.
+ ///
+ /// The alpha value to multiply.
+ /// The new color after the modification.
+ public Color MultiplyA(double a) => new Color((int)Math.Round(A * a), R, G, B);
+
+ ///
+ /// Multiplies the given alpha-percent value to this color.
+ ///
+ /// The alpha value to multiply.
+ /// The new color after the modification.
+ public Color MultiplyAPercent(double aPercent) => new Color(APercent * aPercent, RPercent, GPercent, BPercent);
+
+ ///
+ /// Multiplies the given red value to this color.
+ ///
+ /// The red value to multiply.
+ /// The new color after the modification.
+ public Color MultiplyR(double r) => new Color(A, (int)Math.Round(R * r), G, B);
+
+ ///
+ /// Multiplies the given red-percent value to this color.
+ ///
+ /// The red value to multiply.
+ /// The new color after the modification.
+ public Color MultiplyRPercent(double rPercent) => new Color(APercent, RPercent * rPercent, GPercent, BPercent);
+
+ ///
+ /// Multiplies the given green value to this color.
+ ///
+ /// The green value to multiply.
+ /// The new color after the modification.
+ public Color MultiplyG(double g) => new Color(A, R, (int)Math.Round(G * g), B);
+
+ ///
+ /// Multiplies the given green-percent value to this color.
+ ///
+ /// The green value to multiply.
+ /// The new color after the modification.
+ public Color MultiplyGPercent(double gPercent) => new Color(APercent, RPercent, GPercent * gPercent, BPercent);
+
+ ///
+ /// Multiplies the given blue value to this color.
+ ///
+ /// The blue value to multiply.
+ /// The new color after the modification.
+ public Color MultiplyB(double b) => new Color(A, R, G, (int)Math.Round(B * b));
+
+ ///
+ /// Multiplies the given blue-percent value to this color.
+ ///
+ /// The blue value to multiply.
+ /// The new color after the modification.
+ public Color MultiplyBPercent(double bPercent) => new Color(APercent, RPercent, GPercent, BPercent * bPercent);
+
+ ///
+ /// Multiplies the given hue value to this color.
+ ///
+ /// The hue value to multiply.
+ /// The new color after the modification.
+ public Color MultiplyHue(double hue) => FromHSV(A, Hue * hue, Saturation, Value);
+
+ ///
+ /// Multiplies the given saturation value to this color.
+ ///
+ /// The saturation value to multiply.
+ /// The new color after the modification.
+ public Color MultiplySaturation(double saturation) => FromHSV(A, Hue, Saturation * saturation, Value);
+
+ ///
+ /// Multiplies the given value value to this color.
+ ///
+ /// The value value to multiply.
+ /// The new color after the modification.
+ public Color MultiplyValue(double value) => FromHSV(A, Hue, Saturation, Value * value);
+
+ #endregion
+
+ #region Divide
+
+ ///
+ /// Divides the given RGB values to this color.
+ ///
+ /// The red value to divide.
+ /// The green value to divide.
+ /// The blue value to divide.
+ /// The new color after the modification.
+ public Color DivideRGB(double r, double g, double b) => DivideRGB(1, r, g, b);
+
+ ///
+ /// Divides the given RGB values to this color.
+ ///
+ /// The alpha value to divide.
+ /// The red value to divide.
+ /// The green value to divide.
+ /// The blue value to divide.
+ /// The new color after the modification.
+ public Color DivideRGB(double a, double r, double g, double b)
+ => new Color((int)Math.Round(A / a), (int)Math.Round(R / r), (int)Math.Round(G / g), (int)Math.Round(B / b));
+
+ ///
+ /// Divides the given RGB-percent values to this color.
+ ///
+ /// The red value to divide.
+ /// The green value to divide.
+ /// The blue value to divide.
+ /// The new color after the modification.
+ public Color DividePercent(double rPercent, double gPercent, double bPercent) => DividePercent(1, rPercent, gPercent, bPercent);
+
+ ///
+ /// Divides the given RGB-percent values to this color.
+ ///
+ /// The alpha value to divide.
+ /// The red value to divide.
+ /// The green value to divide.
+ /// The blue value to divide.
+ /// The new color after the modification.
+ public Color DividePercent(double aPercent, double rPercent, double gPercent, double bPercent)
+ => new Color(APercent / aPercent, RPercent / rPercent, GPercent / gPercent, BPercent / bPercent);
+
+ ///
+ /// Divides the given HSV values to this color.
+ ///
+ /// The hue value to divide.
+ /// The saturation value to divide.
+ /// The value value to divide.
+ /// The new color after the modification.
+ public Color DivideHSV(double hue, double saturation, double value) => DivideHSV(1, hue, saturation, value);
+
+ ///
+ /// Divides the given HSV values to this color.
+ ///
+ /// The alpha value to divide.
+ /// The hue value to divide.
+ /// The saturation value to divide.
+ /// The value value to divide.
+ /// The new color after the modification.
+ public Color DivideHSV(double a, double hue, double saturation, double value)
+ => FromHSV((int)Math.Round(A / a), Hue / hue, Saturation / saturation, Value / value);
+
+ ///
+ /// Divides the given alpha value to this color.
+ ///
+ /// The alpha value to divide.
+ /// The new color after the modification.
+ public Color DivideA(double a) => new Color((int)Math.Round(A / a), R, G, B);
+
+ ///
+ /// Divides the given alpha-percent value to this color.
+ ///
+ /// The alpha value to divide.
+ /// The new color after the modification.
+ public Color DivideAPercent(double aPercent) => new Color(APercent / aPercent, RPercent, GPercent, BPercent);
+
+ ///
+ /// Divides the given red value to this color.
+ ///
+ /// The red value to divide.
+ /// The new color after the modification.
+ public Color DivideRValue(double r) => new Color(A, (int)Math.Round(R / r), G, B);
+
+ ///
+ /// Divides the given red-percent value to this color.
+ ///
+ /// The red value to divide.
+ /// The new color after the modification.
+ public Color DivideRPercent(double rPercent) => new Color(APercent, RPercent / rPercent, GPercent, BPercent);
+
+ ///
+ /// Divides the given green value to this color.
+ ///
+ /// The green value to divide.
+ /// The new color after the modification.
+ public Color DivideGValue(double g) => new Color(A, R, (int)Math.Round(G / g), B);
+
+ ///
+ /// Divides the given green-percent value to this color.
+ ///
+ /// The green value to divide.
+ /// The new color after the modification.
+ public Color DivideGPercent(double gPercent) => new Color(APercent, RPercent, GPercent / gPercent, BPercent);
+
+ ///
+ /// Divides the given blue value to this color.
+ ///
+ /// The blue value to divide.
+ /// The new color after the modification.
+ public Color DivideBValue(double b) => new Color(A, R, G, (int)Math.Round(B / b));
+
+ ///
+ /// Divides the given blue-percent value to this color.
+ ///
+ /// The blue value to divide.
+ /// The new color after the modification.
+ public Color DivideBPercent(double bPercent) => new Color(APercent, RPercent, GPercent, BPercent / bPercent);
+
+ ///
+ /// Divides the given hue value to this color.
+ ///
+ /// The hue value to divide.
+ /// The new color after the modification.
+ public Color DivideHue(double hue) => FromHSV(A, Hue / hue, Saturation, Value);
+
+ ///
+ /// Divides the given saturation value to this color.
+ ///
+ /// The saturation value to divide.
+ /// The new color after the modification.
+ public Color DivideSaturation(double saturation) => FromHSV(A, Hue, Saturation / saturation, Value);
+
+ ///
+ /// Divides the given value value to this color.
+ ///
+ /// The value value to divide.
+ /// The new color after the modification.
+ public Color DivideValue(double value) => FromHSV(A, Hue, Saturation, Value / value);
+
+ #endregion
+
+ #region Set
+
+ ///
+ /// Sets the given alpha value of this color.
+ ///
+ /// The alpha value to set.
+ /// The new color after the modification.
+ public Color SetA(int a) => new Color(a, R, G, B);
+
+ ///
+ /// Sets the given alpha-percent value of this color.
+ ///
+ /// The alpha value to set.
+ /// The new color after the modification.
+ public Color SetAPercent(double aPercent) => new Color(aPercent, RPercent, GPercent, BPercent);
+
+ ///
+ /// Sets the given red value of this color.
+ ///
+ /// The red value to set.
+ /// The new color after the modification.
+ public Color SetR(int r) => new Color(A, r, G, B);
+
+ ///
+ /// Sets the given red-percent value of this color.
+ ///
+ /// The red value to set.
+ /// The new color after the modification.
+ public Color SetRPercent(double rPercent) => new Color(APercent, rPercent, GPercent, BPercent);
+
+ ///
+ /// Sets the given green value of this color.
+ ///
+ /// The green value to set.
+ /// The new color after the modification.
+ public Color SetG(int g) => new Color(A, R, g, B);
+
+ ///
+ /// Sets the given green-percent value of this color.
+ ///
+ /// The green value to set.
+ /// The new color after the modification.
+ public Color SetGPercent(double gPercent) => new Color(APercent, RPercent, gPercent, BPercent);
+
+ ///
+ /// Sets the given blue value of this color.
+ ///
+ /// The blue value to set.
+ /// The new color after the modification.
+ public Color SetB(int b) => new Color(A, R, G, b);
+
+ ///
+ /// Sets the given blue-percent value of this color.
+ ///
+ /// The blue value to set.
+ /// The new color after the modification.
+ public Color SetBPercent(double bPercent) => new Color(APercent, RPercent, GPercent, bPercent);
+
+ ///
+ /// Sets the given hue value of this color.
+ ///
+ /// The hue value to set.
+ /// The new color after the modification.
+ public Color SetHue(double hue) => FromHSV(A, hue, Saturation, Value);
+
+ ///
+ /// Sets the given saturation value of this color.
+ ///
+ /// The saturation value to set.
+ /// The new color after the modification.
+ public Color SetSaturation(double saturation) => FromHSV(A, Hue, saturation, Value);
+
+ ///
+ /// Sets the given value value of this color.
+ ///
+ /// The value value to set.
+ /// The new color after the modification.
+ public Color SetValue(double value) => FromHSV(A, Hue, Saturation, value);
+
+ #endregion
+
+ #endregion
+
#endregion
#region Operators
+ ///
+ /// Blends the provided colors as if would've been called on .
+ ///
+ /// The base color.
+ /// The color to blend.
+ /// The blended color.
+ public static Color operator +(Color color1, Color color2) => color1.Blend(color2);
+
///
/// Returns a value that indicates whether two specified are equal.
///
/// The first to compare.
/// The second to compare.
/// true if and are equal; otherwise, false.
- public static bool operator ==(Color color1, Color color2)
- {
- return ReferenceEquals(color1, null) ? ReferenceEquals(color2, null) : color1.Equals(color2);
- }
+ public static bool operator ==(Color color1, Color color2) => color1.Equals(color2);
///
/// Returns a value that indicates whether two specified are equal.
@@ -489,10 +1067,21 @@ namespace RGB.NET.Core
/// The first to compare.
/// The second to compare.
/// true if and are not equal; otherwise, false.
- public static bool operator !=(Color color1, Color color2)
- {
- return !(color1 == color2);
- }
+ public static bool operator !=(Color color1, Color color2) => !(color1 == color2);
+
+ ///
+ /// Converts a of ARGB-components to a .
+ ///
+ /// The containing the components.
+ /// The color.
+ public static implicit operator Color((byte a, byte r, byte g, byte b) components) => new Color(components.a, components.r, components.g, components.b);
+
+ ///
+ /// Converts a of HSV-components to a .
+ ///
+ /// The containing the components.
+ /// The color.
+ public static implicit operator Color((double hue, double saturation, double value) components) => new Color(components.hue, components.saturation, components.value);
#endregion
}
diff --git a/RGB.NET.Core/Leds/Led.cs b/RGB.NET.Core/Leds/Led.cs
index 5854bf6..a97c4bd 100644
--- a/RGB.NET.Core/Leds/Led.cs
+++ b/RGB.NET.Core/Leds/Led.cs
@@ -60,7 +60,7 @@ namespace RGB.NET.Core
///
public Color RequestedColor
{
- get => new Color(_requestedColor);
+ get => _requestedColor;
private set
{
SetProperty(ref _requestedColor, value);
@@ -80,15 +80,7 @@ namespace RGB.NET.Core
set
{
if (!IsLocked)
- {
- // DarthAffe 26.01.2017: DON'T USE THE PROPERTY HERE! Working on the copy doesn't work!
- _requestedColor.Blend(value);
-
- // ReSharper disable ExplicitCallerInfoArgument
- OnPropertyChanged(nameof(RequestedColor));
- OnPropertyChanged(nameof(IsDirty));
- // ReSharper restore ExplicitCallerInfoArgument
- }
+ RequestedColor += value;
}
}
@@ -168,19 +160,13 @@ namespace RGB.NET.Core
/// Converts a to a .
///
/// The to convert.
- public static implicit operator Color(Led led)
- {
- return led?.Color;
- }
+ public static implicit operator Color(Led led) => led?.Color ?? Color.Transparent;
///
/// Converts a to a .
///
/// The to convert.
- public static implicit operator Rectangle(Led led)
- {
- return led?.LedRectangle;
- }
+ public static implicit operator Rectangle(Led led) => led?.LedRectangle;
#endregion
}
diff --git a/RGB.NET.Core/Positioning/Point.cs b/RGB.NET.Core/Positioning/Point.cs
index 0ca16a7..8d05d55 100644
--- a/RGB.NET.Core/Positioning/Point.cs
+++ b/RGB.NET.Core/Positioning/Point.cs
@@ -140,11 +140,11 @@ namespace RGB.NET.Core
}
///
- /// Returns a new representing the substraction of the two provided .
+ /// Returns a new representing the subtraction of the two provided .
///
/// The first .
/// The second .
- /// A new representing the substraction of the two provided .
+ /// A new representing the subtraction of the two provided .
public static Point operator -(Point point1, Point point2)
{
return new Point(point1.X - point2.X, point1.Y - point2.Y);
diff --git a/RGB.NET.Core/Positioning/Size.cs b/RGB.NET.Core/Positioning/Size.cs
index 0e36567..8cc8cd0 100644
--- a/RGB.NET.Core/Positioning/Size.cs
+++ b/RGB.NET.Core/Positioning/Size.cs
@@ -149,11 +149,11 @@ namespace RGB.NET.Core
}
///
- /// Returns a new representing the substraction of the two provided .
+ /// Returns a new representing the subtraction of the two provided .
///
/// The first .
/// The second .
- /// A new representing the substraction of the two provided .
+ /// A new representing the subtraction of the two provided .
public static Size operator -(Size size1, Size size2)
{
return new Size(size1.Width - size2.Width, size1.Height - size2.Height);
diff --git a/RGB.NET.Core/RGB.NET.Core.csproj b/RGB.NET.Core/RGB.NET.Core.csproj
index ae6c793..429140a 100644
--- a/RGB.NET.Core/RGB.NET.Core.csproj
+++ b/RGB.NET.Core/RGB.NET.Core.csproj
@@ -80,7 +80,7 @@
-
+
diff --git a/RGB.NET.Decorators/Brush/FlashDecorator.cs b/RGB.NET.Decorators/Brush/FlashDecorator.cs
index c4d79ba..1d7daff 100644
--- a/RGB.NET.Decorators/Brush/FlashDecorator.cs
+++ b/RGB.NET.Decorators/Brush/FlashDecorator.cs
@@ -72,7 +72,7 @@ namespace RGB.NET.Decorators.Brush
#region Methods
///
- public void ManipulateColor(Rectangle rectangle, BrushRenderTarget renderTarget, ref Color color) => color.APercent = _currentValue;
+ public Color ManipulateColor(Rectangle rectangle, BrushRenderTarget renderTarget, Color color) => color.SetAPercent(_currentValue);
///
protected override void Update(double deltaTime)
diff --git a/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs b/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs
index 1a6bc33..c7a904b 100644
--- a/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs
+++ b/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs
@@ -151,7 +151,7 @@ namespace RGB.NET.Devices.Corsair
for (int i = 0; i < LedMapping.Count; i++)
{
_CorsairLedColor ledColor = (_CorsairLedColor)Marshal.PtrToStructure(readPtr, typeof(_CorsairLedColor));
- colorData.Add((CorsairLedIds)ledColor.ledId, new Color((byte)ledColor.r, (byte)ledColor.g, (byte)ledColor.b));
+ colorData.Add((CorsairLedIds)ledColor.ledId, new Color(ledColor.r, ledColor.g, ledColor.b));
readPtr = new IntPtr(readPtr.ToInt64() + structSize);
}
diff --git a/RGB.NET.WPF/Converter/ColorToSolidColorBrushConverter.cs b/RGB.NET.WPF/Converter/ColorToSolidColorBrushConverter.cs
index c76b64b..4dea27d 100644
--- a/RGB.NET.WPF/Converter/ColorToSolidColorBrushConverter.cs
+++ b/RGB.NET.WPF/Converter/ColorToSolidColorBrushConverter.cs
@@ -15,8 +15,7 @@ namespace RGB.NET.WPF.Converter
///
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
- Core.Color color = value as Core.Color;
- return new SolidColorBrush(color == null
+ return new SolidColorBrush(!(value is Core.Color color)
? Color.FromArgb(0, 0, 0, 0)
: Color.FromArgb(color.A, color.R, color.G, color.B));
}