diff --git a/samples/ColorBlenderWPF/ColorBlenderWPF.csproj b/samples/ColorBlenderWPF/ColorBlenderWPF.csproj index 77f07ed..c049395 100644 --- a/samples/ColorBlenderWPF/ColorBlenderWPF.csproj +++ b/samples/ColorBlenderWPF/ColorBlenderWPF.csproj @@ -10,7 +10,7 @@ Properties ColorBlenderWPF ColorBlenderWPF - v4.5 + v4.6.1 512 diff --git a/samples/ColorBlenderWPF/app.config b/samples/ColorBlenderWPF/app.config index 8747823..fd3b410 100644 --- a/samples/ColorBlenderWPF/app.config +++ b/samples/ColorBlenderWPF/app.config @@ -1,6 +1,6 @@ - + diff --git a/src/ColorBlender/Algorithms/Analogue.cs b/src/ColorBlender/Algorithms/Analogue.cs index aab449d..69b4541 100644 --- a/src/ColorBlender/Algorithms/Analogue.cs +++ b/src/ColorBlender/Algorithms/Analogue.cs @@ -1,6 +1,7 @@ // Copyright (c) Wiesław Šoltés. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; +using ColorBlender.Colors; namespace ColorBlender.Algorithms { @@ -12,34 +13,19 @@ namespace ColorBlender.Algorithms outp.Colors[0] = new HSV(hsv); var w = MathHelpers.HueToWheel(hsv.H); - HSV z = new HSV - { - H = MathHelpers.WheelToHue((w + 30) % 360), - S = hsv.S, - V = hsv.V - }; + HSV z = hsv.WithH(MathHelpers.WheelToHue((w + 30) % 360)); outp.Colors[1] = new HSV(z); - z = new HSV - { - H = MathHelpers.WheelToHue((w + 60) % 360), - S = hsv.S, - V = hsv.V - }; + z = hsv.WithH(MathHelpers.WheelToHue((w + 60) % 360)); outp.Colors[2] = new HSV(z); - z = new HSV - { - S = 0, - H = 0, - V = 100 - hsv.V - }; + z = new HSV(0, 0, 100 - hsv.V); outp.Colors[3] = new HSV(z); - z.V = Math.Round(hsv.V * 1.3) % 100; + z = z.WithV(Math.Round(hsv.V * 1.3) % 100); outp.Colors[4] = new HSV(z); - z.V = Math.Round(hsv.V / 1.3) % 100; + z = z.WithV(Math.Round(hsv.V / 1.3) % 100); outp.Colors[5] = new HSV(z); return outp; diff --git a/src/ColorBlender/Algorithms/ClassicBlend.cs b/src/ColorBlender/Algorithms/ClassicBlend.cs index 9e83748..82eee80 100644 --- a/src/ColorBlender/Algorithms/ClassicBlend.cs +++ b/src/ColorBlender/Algorithms/ClassicBlend.cs @@ -1,5 +1,6 @@ // Copyright (c) Wiesław Šoltés. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using ColorBlender.Colors; namespace ColorBlender.Algorithms { @@ -10,71 +11,97 @@ namespace ColorBlender.Algorithms Blend outp = new Blend(); outp.Colors[0] = new HSV(hsv); - HSV y = new HSV(); - HSV yx = new HSV(); - - y.S = hsv.S; - y.H = hsv.H; - if (hsv.V > 70) { y.V = hsv.V - 30; } else { y.V = hsv.V + 30; }; + HSV y = hsv.WithV(hsv.V > 70 ? hsv.V - 30 : hsv.V + 30); outp.Colors[1] = new HSV(y); + HSV yx = new HSV(); + if ((hsv.H >= 0) && (hsv.H < 30)) { - yx.H = y.H = hsv.H + 30; yx.S = y.S = hsv.S; y.V = hsv.V; - if (hsv.V > 70) { yx.V = hsv.V - 30; } else { yx.V = hsv.V + 30; } + y = new HSV( + hsv.H + 30, + hsv.S, + hsv.V); + + yx = new HSV( + hsv.H + 30, + hsv.S, + hsv.V > 70 ? hsv.V - 30 : hsv.V + 30); } if ((hsv.H >= 30) && (hsv.H < 60)) { - yx.H = y.H = hsv.H + 150; - y.S = MathHelpers.RC(hsv.S - 30, 100); - y.V = MathHelpers.RC(hsv.V - 20, 100); - yx.S = MathHelpers.RC(hsv.S - 50, 100); - yx.V = MathHelpers.RC(hsv.V + 20, 100); + y = new HSV( + hsv.H + 150, + MathHelpers.RC(hsv.S - 30, 100), + MathHelpers.RC(hsv.V - 20, 100)); + + yx = new HSV( + hsv.H + 150, + MathHelpers.RC(hsv.S - 50, 100), + MathHelpers.RC(hsv.V + 20, 100)); } if ((hsv.H >= 60) && (hsv.H < 180)) { - yx.H = y.H = hsv.H - 40; - y.S = yx.S = hsv.S; - y.V = hsv.V; if (hsv.V > 70) { yx.V = hsv.V - 30; } else { yx.V = hsv.V + 30; } + y = new HSV( + hsv.H - 40, + hsv.S, + hsv.V); + + yx = new HSV( + hsv.H - 40, + hsv.S, + hsv.V > 70 ? hsv.V - 30 : hsv.V + 30); } if ((hsv.H >= 180) && (hsv.H < 220)) { - yx.H = hsv.H - 170; - y.H = hsv.H - 160; - yx.S = y.S = hsv.S; - y.V = hsv.V; - if (hsv.V > 70) { yx.V = hsv.V - 30; } else { yx.V = hsv.V + 30; } + y = new HSV( + hsv.H - 160, + hsv.S, + hsv.V); + yx = new HSV( + hsv.H - 170, + hsv.S, + hsv.V > 70 ? hsv.V - 30 : hsv.V + 30); } + if ((hsv.H >= 220) && (hsv.H < 300)) { - yx.H = y.H = hsv.H; - yx.S = y.S = MathHelpers.RC(hsv.S - 40, 100); - y.V = hsv.V; - if (hsv.V > 70) { yx.V = hsv.V - 30; } else { yx.V = hsv.V + 30; } + yx = new HSV( + hsv.H, + MathHelpers.RC(hsv.S - 40, 100), + hsv.V); + + yx = new HSV( + hsv.H, + MathHelpers.RC(hsv.S - 40, 100), + hsv.V > 70 ? hsv.V - 30 : hsv.V + 30); } + if (hsv.H >= 300) { - if (hsv.S > 50) { y.S = yx.S = hsv.S - 40; } else { y.S = yx.S = hsv.S + 40; } - yx.H = y.H = (hsv.H + 20) % 360; - y.V = hsv.V; - if (hsv.V > 70) { yx.V = hsv.V - 30; } else { yx.V = hsv.V + 30; } + yx = new HSV( + (hsv.H + 20) % 360, + hsv.S > 50 ? hsv.S - 40 : hsv.S + 40, + hsv.V); + + yx = new HSV( + (hsv.H + 20) % 360, + hsv.S > 50 ? hsv.S - 40 : hsv.S + 40, + hsv.V > 70 ? hsv.V - 30 : hsv.V + 30); } outp.Colors[2] = new HSV(y); + outp.Colors[3] = new HSV(yx); - y.H = 0; - y.S = 0; - y.V = 100 - hsv.V; + y = new HSV(0, 0, 100 - hsv.V); outp.Colors[4] = new HSV(y); - y.H = 0; - y.S = 0; - y.V = hsv.V; + y = new HSV(0, 0, hsv.V); outp.Colors[5] = new HSV(y); return outp; diff --git a/src/ColorBlender/Algorithms/ColorExplorer.cs b/src/ColorBlender/Algorithms/ColorExplorer.cs index 211c043..dee6d04 100644 --- a/src/ColorBlender/Algorithms/ColorExplorer.cs +++ b/src/ColorBlender/Algorithms/ColorExplorer.cs @@ -1,6 +1,7 @@ // Copyright (c) Wiesław Šoltés. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; +using ColorBlender.Colors; namespace ColorBlender.Algorithms { @@ -11,31 +12,24 @@ namespace ColorBlender.Algorithms Blend outp = new Blend(); outp.Colors[0] = new HSV(hsv); - HSV z = new HSV - { - H = hsv.H, - S = Math.Round(hsv.S * 0.3), - V = Math.Min(Math.Round(hsv.V * 1.3), 100) - }; + HSV z = new HSV( + hsv.H, + Math.Round(hsv.S * 0.3), + Math.Min(Math.Round(hsv.V * 1.3), 100)); outp.Colors[1] = new HSV(z); - z = new HSV - { - H = (hsv.H + 300) % 360, - S = hsv.S, - V = hsv.V - }; + z = hsv.WithH((hsv.H + 300) % 360); outp.Colors[3] = new HSV(z); - z.S = Math.Min(Math.Round(z.S * 1.2), 100); - z.V = Math.Min(Math.Round(z.V * 0.5), 100); + z = z.WithS(Math.Min(Math.Round(z.S * 1.2), 100)); + z = z.WithV(Math.Min(Math.Round(z.V * 0.5), 100)); outp.Colors[2] = new HSV(z); - z.S = 0; - z.V = (hsv.V + 50) % 100; + z = z.WithS(0); + z = z.WithV((hsv.V + 50) % 100); outp.Colors[4] = new HSV(z); - z.V = (z.V + 50) % 100; + z = z.WithV((z.V + 50) % 100); outp.Colors[5] = new HSV(z); return outp; diff --git a/src/ColorBlender/Algorithms/Complementary.cs b/src/ColorBlender/Algorithms/Complementary.cs index 90a2253..7a9a365 100644 --- a/src/ColorBlender/Algorithms/Complementary.cs +++ b/src/ColorBlender/Algorithms/Complementary.cs @@ -1,6 +1,7 @@ // Copyright (c) Wiesław Šoltés. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; +using ColorBlender.Colors; namespace ColorBlender.Algorithms { @@ -11,33 +12,25 @@ namespace ColorBlender.Algorithms Blend outp = new Blend(); outp.Colors[0] = new HSV(hsv); - HSV z = new HSV - { - H = hsv.H, - S = (hsv.S > 50) ? (hsv.S * 0.5) : (hsv.S * 2), - V = (hsv.V < 50) ? (Math.Min(hsv.V * 1.5, 100)) : (hsv.V / 1.5) - }; + HSV z = new HSV( + hsv.H, + (hsv.S > 50) ? (hsv.S * 0.5) : (hsv.S * 2), + (hsv.V < 50) ? (Math.Min(hsv.V * 1.5, 100)) : (hsv.V / 1.5)); outp.Colors[1] = new HSV(z); var w = MathHelpers.HueToWheel(hsv.H); - z.H = MathHelpers.WheelToHue((w + 180) % 360); - z.S = hsv.S; - z.V = hsv.V; + + z = hsv.WithH(MathHelpers.WheelToHue((w + 180) % 360)); outp.Colors[2] = new HSV(z); - z.S = (z.S > 50) ? (z.S * 0.5) : (z.S * 2); - z.V = (z.V < 50) ? (Math.Min(z.V * 1.5, 100)) : (z.V / 1.5); + z = z.WithS((z.S > 50) ? (z.S * 0.5) : (z.S * 2)); + z = z.WithV((z.V < 50) ? (Math.Min(z.V * 1.5, 100)) : (z.V / 1.5)); outp.Colors[3] = new HSV(z); - z = new HSV - { - S = 0, - H = 0, - V = hsv.V - }; + z = new HSV(0, 0, hsv.V); outp.Colors[4] = new HSV(z); - z.V = 100 - hsv.V; + z = z.WithV(100 - hsv.V); outp.Colors[5] = new HSV(z); return outp; diff --git a/src/ColorBlender/Algorithms/SingleHue.cs b/src/ColorBlender/Algorithms/SingleHue.cs index 530104e..a437200 100644 --- a/src/ColorBlender/Algorithms/SingleHue.cs +++ b/src/ColorBlender/Algorithms/SingleHue.cs @@ -1,5 +1,6 @@ // Copyright (c) Wiesław Šoltés. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using ColorBlender.Colors; namespace ColorBlender.Algorithms { @@ -10,28 +11,23 @@ namespace ColorBlender.Algorithms Blend outp = new Blend(); outp.Colors[0] = new HSV(hsv); - HSV z = new HSV - { - H = hsv.H, - S = hsv.S, - V = hsv.V + ((hsv.V < 50) ? 20 : -20) - }; + HSV z = hsv.WithV(hsv.V + ((hsv.V < 50) ? 20 : -20)); outp.Colors[1] = new HSV(z); - z.S = hsv.S; - z.V = hsv.V + ((hsv.V < 50) ? 40 : -40); + z = z.WithS(hsv.S); + z = z.WithV(hsv.V + ((hsv.V < 50) ? 40 : -40)); outp.Colors[2] = new HSV(z); - z.S = hsv.S + ((hsv.S < 50) ? 20 : -20); - z.V = hsv.V; + z = z.WithS(hsv.S + ((hsv.S < 50) ? 20 : -20)); + z = z.WithV(hsv.V); outp.Colors[3] = new HSV(z); - z.S = hsv.S + ((hsv.S < 50) ? 40 : -40); - z.V = hsv.V; + z = z.WithS(hsv.S + ((hsv.S < 50) ? 40 : -40)); + z = z.WithV(hsv.V); outp.Colors[4] = new HSV(z); - z.S = hsv.S + ((hsv.S < 50) ? 40 : -40); - z.V = hsv.V + ((hsv.V < 50) ? 40 : -40); + z = z.WithS(hsv.S + ((hsv.S < 50) ? 40 : -40)); + z = z.WithV(hsv.V + ((hsv.V < 50) ? 40 : -40)); outp.Colors[5] = new HSV(z); return outp; diff --git a/src/ColorBlender/Algorithms/SplitComplementary.cs b/src/ColorBlender/Algorithms/SplitComplementary.cs index 98a1c2a..75828fc 100644 --- a/src/ColorBlender/Algorithms/SplitComplementary.cs +++ b/src/ColorBlender/Algorithms/SplitComplementary.cs @@ -1,5 +1,6 @@ // Copyright (c) Wiesław Šoltés. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using ColorBlender.Colors; namespace ColorBlender.Algorithms { @@ -11,33 +12,23 @@ namespace ColorBlender.Algorithms outp.Colors[0] = new HSV(hsv); var w = MathHelpers.HueToWheel(hsv.H); - HSV z = new HSV - { - H = hsv.H, - S = hsv.S, - V = hsv.V - }; - z.H = MathHelpers.WheelToHue((w + 150) % 360); - z.S = hsv.S; - z.V = hsv.V; + HSV z = hsv.WithH(MathHelpers.WheelToHue((w + 150) % 360)); outp.Colors[1] = new HSV(z); - z.H = MathHelpers.WheelToHue((w + 210) % 360); - z.S = hsv.S; - z.V = hsv.V; + z = hsv.WithH(MathHelpers.WheelToHue((w + 210) % 360)); outp.Colors[2] = new HSV(z); - z.S = 0; - z.V = hsv.S; + z = z.WithS(0); + z = z.WithV(hsv.S); outp.Colors[3] = new HSV(z); - z.S = 0; - z.V = hsv.V; + z = z.WithS(0); + z = z.WithV(hsv.V); outp.Colors[4] = new HSV(z); - z.S = 0; - z.V = (100 - hsv.V); + z = z.WithS(0); + z = z.WithV(100 - hsv.V); outp.Colors[5] = new HSV(z); return outp; diff --git a/src/ColorBlender/Algorithms/Square.cs b/src/ColorBlender/Algorithms/Square.cs index 68cfb31..4d99528 100644 --- a/src/ColorBlender/Algorithms/Square.cs +++ b/src/ColorBlender/Algorithms/Square.cs @@ -1,5 +1,6 @@ // Copyright (c) Wiesław Šoltés. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using ColorBlender.Colors; namespace ColorBlender.Algorithms { @@ -11,28 +12,20 @@ namespace ColorBlender.Algorithms outp.Colors[0] = new HSV(hsv); var w = MathHelpers.HueToWheel(hsv.H); - HSV z = new HSV - { - H = MathHelpers.WheelToHue((w + 90) % 360), - S = hsv.S, - V = hsv.V - }; + + HSV z = hsv.WithH(MathHelpers.WheelToHue((w + 90) % 360)); outp.Colors[1] = new HSV(z); - z.H = MathHelpers.WheelToHue((w + 180) % 360); - z.S = hsv.S; - z.V = hsv.V; + z = hsv.WithH(MathHelpers.WheelToHue((w + 180) % 360)); outp.Colors[2] = new HSV(z); - z.H = MathHelpers.WheelToHue((w + 270) % 360); - z.S = hsv.S; - z.V = hsv.V; + z = hsv.WithH(MathHelpers.WheelToHue((w + 270) % 360)); outp.Colors[3] = new HSV(z); - z.S = 0; + z = z.WithS(0); outp.Colors[4] = new HSV(z); - z.V = 100 - z.V; + z = z.WithV(100 - z.V); outp.Colors[5] = new HSV(z); return outp; diff --git a/src/ColorBlender/Algorithms/Triadic.cs b/src/ColorBlender/Algorithms/Triadic.cs index 01231b8..c00f8f2 100644 --- a/src/ColorBlender/Algorithms/Triadic.cs +++ b/src/ColorBlender/Algorithms/Triadic.cs @@ -1,5 +1,6 @@ // Copyright (c) Wiesław Šoltés. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using ColorBlender.Colors; namespace ColorBlender.Algorithms { @@ -10,35 +11,21 @@ namespace ColorBlender.Algorithms Blend outp = new Blend(); outp.Colors[0] = new HSV(hsv); - var w = MathHelpers.HueToWheel(hsv.H); - HSV z = new HSV - { - S = hsv.S, - H = hsv.H, - V = 100 - hsv.V - }; + double w = MathHelpers.HueToWheel(hsv.H); + + HSV z = hsv.WithV(100 - hsv.V); outp.Colors[1] = new HSV(z); - z = new HSV - { - H = MathHelpers.WheelToHue((w + 120) % 360), - S = hsv.S, - V = hsv.V - }; + z = hsv.WithH(MathHelpers.WheelToHue((w + 120) % 360)); outp.Colors[2] = new HSV(z); - z.V = 100 - z.V; + z = z.WithV(100 - z.V); outp.Colors[3] = new HSV(z); - z = new HSV - { - H = MathHelpers.WheelToHue((w + 240) % 360), - S = hsv.S, - V = hsv.V - }; + z = hsv.WithH(MathHelpers.WheelToHue((w + 240) % 360)); outp.Colors[4] = new HSV(z); - z.V = 100 - z.V; + z = z.WithV(100 - z.V); outp.Colors[5] = new HSV(z); return outp; diff --git a/src/ColorBlender/Blend.cs b/src/ColorBlender/Blend.cs index d6c06bf..0f77e23 100644 --- a/src/ColorBlender/Blend.cs +++ b/src/ColorBlender/Blend.cs @@ -1,5 +1,6 @@ // Copyright (c) Wiesław Šoltés. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using ColorBlender.Colors; namespace ColorBlender { diff --git a/src/ColorBlender/ColorBlender.csproj b/src/ColorBlender/ColorBlender.csproj index 54c3f8e..976a3c7 100644 --- a/src/ColorBlender/ColorBlender.csproj +++ b/src/ColorBlender/ColorBlender.csproj @@ -16,4 +16,8 @@ color;colorblender;palette;design;colors;hsv;rgb + + diff --git a/src/ColorBlender/ColorMatch.cs b/src/ColorBlender/ColorMatch.cs index b986013..35a31cc 100644 --- a/src/ColorBlender/ColorMatch.cs +++ b/src/ColorBlender/ColorMatch.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using ColorBlender.Algorithms; +using ColorBlender.Colors; namespace ColorBlender { @@ -52,29 +53,19 @@ namespace ColorBlender private double AddLimit(double x, double d, double min, double max) { x = x + d; - if (x < min) return min; - if (x > max) return max; - if ((x >= min) && (x <= max)) return x; + if (x < min) + return min; + if (x > max) + return max; + if ((x >= min) && (x <= max)) + return x; return double.NaN; } private RGB HsvVariation(HSV hsv, double addsat, double addval) { - var rgbobj = new RGB(); - var hsvobj = new HSV - { - H = hsv.H, - S = hsv.S, - V = hsv.V - }; - - hsvobj.S = AddLimit(hsvobj.S, addsat, 0, 99); - hsvobj.V = AddLimit(hsvobj.V, addval, 0, 99); - - rgbobj = hsvobj.ToRGB(); - - return rgbobj; + return new HSV(hsv.H, AddLimit(hsv.S, addsat, 0, 99), AddLimit(hsv.V, addval, 0, 99)).ToRGB(); } public void UpdateVariationsRGB() diff --git a/src/ColorBlender/Colors/HSV.cs b/src/ColorBlender/Colors/HSV.cs new file mode 100644 index 0000000..4d4dc41 --- /dev/null +++ b/src/ColorBlender/Colors/HSV.cs @@ -0,0 +1,106 @@ +// Copyright (c) Wiesław Šoltés. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +using System; + +namespace ColorBlender.Colors +{ + public readonly struct HSV + { + public double H { get; } + public double S { get; } + public double V { get; } + + public HSV(double h, double s, double v) + { + H = h; + S = s; + V = v; + } + + public HSV(HSV hsv) + { + H = hsv.H; + S = hsv.S; + V = hsv.V; + } + + public HSV(RGB rgb) + { + HSV hsv = rgb.ToHSV(); + H = hsv.H; + S = hsv.S; + V = hsv.V; + } + + public HSV WithH(double h) => new HSV(h, S, V); + + public HSV WithS(double s) => new HSV(H, s, V); + + public HSV WithV(double v) => new HSV(H, S, v); + + public RGB ToRGB() => ToRGB(H, S, V); + + public static RGB ToRGB(double h, double s, double v) + { + double R = default; + double G = default; + double B = default; + + if (s == 0) + { + R = G = B = Math.Round(v * 2.55); + return new RGB(R, G, B); + } + + s = s / 100; + v = v / 100; + h /= 60; + + var i = Math.Floor(h); + var f = h - i; + var p = v * (1 - s); + var q = v * (1 - s * f); + var t = v * (1 - s * (1 - f)); + + switch ((int)i) + { + case 0: + R = v; + G = t; + B = p; + break; + case 1: + R = q; + G = v; + B = p; + break; + case 2: + R = p; + G = v; + B = t; + break; + case 3: + R = p; + G = q; + B = v; + break; + case 4: + R = t; + G = p; + B = v; + break; + default: + R = v; + G = p; + B = q; + break; + } + + R = Math.Round(R * 255); + G = Math.Round(G * 255); + B = Math.Round(B * 255); + + return new RGB(R, G, B); + } + } +} diff --git a/src/ColorBlender/Colors/RGB.cs b/src/ColorBlender/Colors/RGB.cs new file mode 100644 index 0000000..2e5abd5 --- /dev/null +++ b/src/ColorBlender/Colors/RGB.cs @@ -0,0 +1,117 @@ +// Copyright (c) Wiesław Šoltés. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +using System; + +namespace ColorBlender.Colors +{ + public readonly struct RGB + { + public double R { get; } + public double G { get; } + public double B { get; } + + public RGB(double r, double g, double b) + { + R = r; + G = g; + B = b; + } + + public RGB(RGB rgb) + { + R = rgb.R; + G = rgb.G; + B = rgb.B; + } + + public RGB(HSV hsv) + { + RGB rgb = hsv.ToRGB(); + R = rgb.R; + G = rgb.G; + B = rgb.B; + } + + public RGB WithR(double r) => new RGB(r, G, B); + + public RGB WithG(double g) => new RGB(R, g, B); + + public RGB WithB(double b) => new RGB(R, G, b); + + public HSV ToHSV() => ToHSV(R, G, B); + + public static HSV ToHSV(double r, double g, double b) + { + double H = default; + double S = default; + double V = default; + + var m = r; + + if (g < m) + { + m = g; + } + + if (b < m) + { + m = b; + } + + var v = r; + + if (g > v) + { + v = g; + } + + if (b > v) + { + v = b; + } + + var value = 100 * v / 255; + var delta = v - m; + + if (v == 0.0) + { + S = 0; + } + else + { + S = 100 * delta / v; + } + + if (S == 0) + { + H = 0; + } + else + { + if (r == v) + { + H = 60.0 * (g - b) / delta; + } + else if (g == v) + { + H = 120.0 + 60.0 * (b - r) / delta; + } + else if (b == v) + { + H = 240.0 + 60.0 * (r - g) / delta; + } + + if (H < 0.0) + { + H = H + 360.0; + } + } + + H = Math.Round(H); + S = Math.Round(S); + V = Math.Round(value); + + return new HSV(H, S, V); + } + } +} diff --git a/src/ColorBlender/HSV.cs b/src/ColorBlender/HSV.cs deleted file mode 100644 index 5d7fc5c..0000000 --- a/src/ColorBlender/HSV.cs +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) Wiesław Šoltés. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System; - -namespace ColorBlender -{ - public class HSV - { - public double H { get; set; } - public double S { get; set; } - public double V { get; set; } - - public HSV() - { - } - - public HSV(double h, double s, double v) - { - this.H = h; - this.S = s; - this.V = v; - } - - public HSV(HSV hs) - { - this.H = hs.H; - this.S = hs.S; - this.V = hs.V; - } - - public HSV(RGB rg) - { - HSV hs = rg.ToHSV(); - this.H = hs.H; - this.S = hs.S; - this.V = hs.V; - } - - public RGB ToRGB() - { - RGB rg = new RGB(); - HSV hsx = new HSV(this.H, this.S, this.V); - - if (hsx.S == 0) - { - rg.R = rg.G = rg.B = Math.Round(hsx.V * 2.55); return (rg); - } - - hsx.S = hsx.S / 100; - hsx.V = hsx.V / 100; - hsx.H /= 60; - - var i = Math.Floor(hsx.H); - var f = hsx.H - i; - var p = hsx.V * (1 - hsx.S); - var q = hsx.V * (1 - hsx.S * f); - var t = hsx.V * (1 - hsx.S * (1 - f)); - - switch ((int)i) - { - case 0: rg.R = hsx.V; rg.G = t; rg.B = p; break; - case 1: rg.R = q; rg.G = hsx.V; rg.B = p; break; - case 2: rg.R = p; rg.G = hsx.V; rg.B = t; break; - case 3: rg.R = p; rg.G = q; rg.B = hsx.V; break; - case 4: rg.R = t; rg.G = p; rg.B = hsx.V; break; - default: rg.R = hsx.V; rg.G = p; rg.B = q; break; - } - - rg.R = Math.Round(rg.R * 255); - rg.G = Math.Round(rg.G * 255); - rg.B = Math.Round(rg.B * 255); - - return rg; - } - } -} diff --git a/src/ColorBlender/RGB.cs b/src/ColorBlender/RGB.cs deleted file mode 100644 index de5884f..0000000 --- a/src/ColorBlender/RGB.cs +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) Wiesław Šoltés. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System; - -namespace ColorBlender -{ - public class RGB - { - public double R { get; set; } - public double G { get; set; } - public double B { get; set; } - - public RGB() - { - } - - public RGB(double r, double g, double b) - { - this.R = r; - this.G = g; - this.B = b; - } - - public RGB(RGB rg) - { - this.R = rg.R; - this.G = rg.G; - this.B = rg.B; - } - - public RGB(HSV hs) - { - RGB rg = hs.ToRGB(); - this.R = rg.R; - this.G = rg.G; - this.B = rg.B; - } - - public HSV ToHSV() - { - HSV hs = new HSV(); - RGB rg = new RGB(this.R, this.G, this.B); - - var m = rg.R; - if (rg.G < m) { m = rg.G; } - if (rg.B < m) { m = rg.B; } - var v = rg.R; - if (rg.G > v) { v = rg.G; } - if (rg.B > v) { v = rg.B; } - var value = 100 * v / 255; - var delta = v - m; - if (v == 0.0) { hs.S = 0; } else { hs.S = 100 * delta / v; } - - if (hs.S == 0) { hs.H = 0; } - else - { - if (rg.R == v) { hs.H = 60.0 * (rg.G - rg.B) / delta; } - else if (rg.G == v) { hs.H = 120.0 + 60.0 * (rg.B - rg.R) / delta; } - else if (rg.B == v) { hs.H = 240.0 + 60.0 * (rg.R - rg.G) / delta; } - if (hs.H < 0.0) { hs.H = hs.H + 360.0; } - } - - hs.H = Math.Round(hs.H); - hs.S = Math.Round(hs.S); - hs.V = Math.Round(value); - - return hs; - } - } -} diff --git a/src/WPF.Controls.ColorBlender/ColorExtensions.cs b/src/WPF.Controls.ColorBlender/Extensions.cs similarity index 94% rename from src/WPF.Controls.ColorBlender/ColorExtensions.cs rename to src/WPF.Controls.ColorBlender/Extensions.cs index dab7449..e8fefbc 100644 --- a/src/WPF.Controls.ColorBlender/ColorExtensions.cs +++ b/src/WPF.Controls.ColorBlender/Extensions.cs @@ -2,11 +2,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; using System.Windows.Media; -using ColorBlender; +using ColorBlender.Colors; namespace WPF.Controls.ColorBlender { - public static class ColorExtensions + public static class Extensions { public static RGB ToRGB(this Color c) { diff --git a/src/WPF.Controls.ColorBlender/WPF.Controls.ColorBlender.csproj b/src/WPF.Controls.ColorBlender/WPF.Controls.ColorBlender.csproj index 5fa8821..61c6d96 100644 --- a/src/WPF.Controls.ColorBlender/WPF.Controls.ColorBlender.csproj +++ b/src/WPF.Controls.ColorBlender/WPF.Controls.ColorBlender.csproj @@ -8,10 +8,11 @@ library WPF.Controls.ColorBlender WPF.Controls.ColorBlender - v4.5 + v4.6.1 512 {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 4 + true @@ -48,7 +49,7 @@ ColorBlender.xaml - + Code diff --git a/tests/ColorBlender.UnitTests/AlgorithmsTests.cs b/tests/ColorBlender.UnitTests/AlgorithmsTests.cs index afd2054..ed41d70 100644 --- a/tests/ColorBlender.UnitTests/AlgorithmsTests.cs +++ b/tests/ColorBlender.UnitTests/AlgorithmsTests.cs @@ -1,6 +1,7 @@ // Copyright (c) Wiesław Šoltés. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using ColorBlender.Algorithms; +using ColorBlender.Colors; using Xunit; namespace ColorBlender.UnitTests diff --git a/tests/ColorBlender.UnitTests/BlendTests.cs b/tests/ColorBlender.UnitTests/BlendTests.cs index 0d3c52c..b682888 100644 --- a/tests/ColorBlender.UnitTests/BlendTests.cs +++ b/tests/ColorBlender.UnitTests/BlendTests.cs @@ -1,5 +1,6 @@ // Copyright (c) Wiesław Šoltés. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using ColorBlender.Colors; using Xunit; namespace ColorBlender.UnitTests