This commit is contained in:
Wiesław Šoltés 2017-10-07 09:54:59 +02:00
Родитель 5bb4339824
Коммит 2832f27493
22 изменённых файлов: 610 добавлений и 351 удалений

Просмотреть файл

@ -9,6 +9,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ColorBlender", "src\ColorBl
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ColorBlenderAvalonia", "src\ColorBlenderAvalonia\ColorBlenderAvalonia.csproj", "{D6EC3C00-F0B9-4531-9563-3487B7ED3512}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{BE9A54A0-F80F-43A7-90F4-98A147169F9B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{D57E2975-0E47-4153-B3ED-3C4D0252EB22}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{9B03B35A-F57E-4BCB-9990-36FB6D1E8787}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ColorBlender.UnitTests", "tests\ColorBlender.UnitTests\ColorBlender.UnitTests.csproj", "{81B01D79-7142-4C77-84FC-26FAACC0D308}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -27,10 +35,20 @@ Global
{D6EC3C00-F0B9-4531-9563-3487B7ED3512}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D6EC3C00-F0B9-4531-9563-3487B7ED3512}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D6EC3C00-F0B9-4531-9563-3487B7ED3512}.Release|Any CPU.Build.0 = Release|Any CPU
{81B01D79-7142-4C77-84FC-26FAACC0D308}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{81B01D79-7142-4C77-84FC-26FAACC0D308}.Debug|Any CPU.Build.0 = Debug|Any CPU
{81B01D79-7142-4C77-84FC-26FAACC0D308}.Release|Any CPU.ActiveCfg = Release|Any CPU
{81B01D79-7142-4C77-84FC-26FAACC0D308}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{F42E593E-39A3-4C44-A909-1AE1FEBAFA37} = {D57E2975-0E47-4153-B3ED-3C4D0252EB22}
{B52C44BA-D099-42E8-94A7-5234E08480FD} = {BE9A54A0-F80F-43A7-90F4-98A147169F9B}
{D6EC3C00-F0B9-4531-9563-3487B7ED3512} = {D57E2975-0E47-4153-B3ED-3C4D0252EB22}
{81B01D79-7142-4C77-84FC-26FAACC0D308} = {9B03B35A-F57E-4BCB-9990-36FB6D1E8787}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5C5DD029-8617-4D20-829C-DA0F7E582C6E}
EndGlobalSection

Просмотреть файл

@ -13,6 +13,24 @@ ColorBlender .NET version is based on sources from: http://www.colorblender.com/
The old version of ColorBlender can be found here: http://www.colormatch5k.com/
The new version of ColorBlender can be found here: http://www.colorexplorer.com/colormatch.aspx
## Algorithms
Color matching algorithms:
* classic - ColorMatch 5K Classic
* colorexplorer - ColorExplorer - "Sweet Spot Offset"
* singlehue - Single Hue
* complementary - Complementary
* splitcomplementary - Split-Complementary
* analogue - Analogue
* triadic - Triadic
* square - Square
All work is done in HSV color space, because all
calculations are based on hue, saturation and value of the working color.
The hue spectrum is divided into sections, are the matching colors are
calculated differently depending on the hue of the color.
## Screenshots
![](images/avalonia.png)

Просмотреть файл

@ -11,35 +11,35 @@ namespace ColorBlender.Algorithms
Blend outp = new Blend();
outp.Colors[0] = new HSV(hsv);
var w = MathHelpers.HueToWheel(hsv.h);
var w = MathHelpers.HueToWheel(hsv.H);
HSV z = new HSV
{
h = MathHelpers.WheelToHue((w + 30) % 360),
s = hsv.s,
v = hsv.v
H = MathHelpers.WheelToHue((w + 30) % 360),
S = hsv.S,
V = hsv.V
};
outp.Colors[1] = new HSV(z);
z = new HSV
{
h = MathHelpers.WheelToHue((w + 60) % 360),
s = hsv.s,
v = hsv.v
H = MathHelpers.WheelToHue((w + 60) % 360),
S = hsv.S,
V = hsv.V
};
outp.Colors[2] = new HSV(z);
z = new HSV
{
s = 0,
h = 0,
v = 100 - hsv.v
S = 0,
H = 0,
V = 100 - hsv.V
};
outp.Colors[3] = new HSV(z);
z.v = Math.Round(hsv.v * 1.3) % 100;
z.V = Math.Round(hsv.V * 1.3) % 100;
outp.Colors[4] = new HSV(z);
z.v = Math.Round(hsv.v / 1.3) % 100;
z.V = Math.Round(hsv.V / 1.3) % 100;
outp.Colors[5] = new HSV(z);
return outp;

Просмотреть файл

@ -13,68 +13,68 @@ namespace ColorBlender.Algorithms
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; };
y.S = hsv.S;
y.H = hsv.H;
if (hsv.V > 70) { y.V = hsv.V - 30; } else { y.V = hsv.V + 30; };
outp.Colors[1] = new HSV(y);
if ((hsv.h >= 0) && (hsv.h < 30))
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; }
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; }
}
if ((hsv.h >= 30) && (hsv.h < 60))
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);
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);
}
if ((hsv.h >= 60) && (hsv.h < 180))
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; }
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; }
}
if ((hsv.h >= 180) && (hsv.h < 220))
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; }
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; }
}
if ((hsv.h >= 220) && (hsv.h < 300))
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.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; }
}
if (hsv.h >= 300)
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; }
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; }
}
outp.Colors[2] = new HSV(y);
outp.Colors[3] = new HSV(yx);
y.h = 0;
y.s = 0;
y.v = 100 - hsv.v;
y.H = 0;
y.S = 0;
y.V = 100 - hsv.V;
outp.Colors[4] = new HSV(y);
y.h = 0;
y.s = 0;
y.v = hsv.v;
y.H = 0;
y.S = 0;
y.V = hsv.V;
outp.Colors[5] = new HSV(y);
return outp;

Просмотреть файл

@ -13,29 +13,29 @@ namespace ColorBlender.Algorithms
HSV z = new HSV
{
h = hsv.h,
s = Math.Round(hsv.s * 0.3),
v = Math.Min(Math.Round(hsv.v * 1.3), 100)
H = hsv.H,
S = Math.Round(hsv.S * 0.3),
V = 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
H = (hsv.H + 300) % 360,
S = hsv.S,
V = hsv.V
};
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.S = Math.Min(Math.Round(z.S * 1.2), 100);
z.V = 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.S = 0;
z.V = (hsv.V + 50) % 100;
outp.Colors[4] = new HSV(z);
z.v = (z.v + 50) % 100;
z.V = (z.V + 50) % 100;
outp.Colors[5] = new HSV(z);
return outp;

Просмотреть файл

@ -13,31 +13,31 @@ namespace ColorBlender.Algorithms
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)
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)
};
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;
var w = MathHelpers.HueToWheel(hsv.H);
z.H = MathHelpers.WheelToHue((w + 180) % 360);
z.S = hsv.S;
z.V = hsv.V;
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.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);
outp.Colors[3] = new HSV(z);
z = new HSV
{
s = 0,
h = 0,
v = hsv.v
S = 0,
H = 0,
V = hsv.V
};
outp.Colors[4] = new HSV(z);
z.v = 100 - hsv.v;
z.V = 100 - hsv.V;
outp.Colors[5] = new HSV(z);
return outp;

Просмотреть файл

@ -12,26 +12,26 @@ namespace ColorBlender.Algorithms
HSV z = new HSV
{
h = hsv.h,
s = hsv.s,
v = hsv.v + ((hsv.v < 50) ? 20 : -20)
H = hsv.H,
S = hsv.S,
V = 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.S = hsv.S;
z.V = 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.S = hsv.S + ((hsv.S < 50) ? 20 : -20);
z.V = hsv.V;
outp.Colors[3] = new HSV(z);
z.s = hsv.s + ((hsv.s < 50) ? 40 : -40);
z.v = hsv.v;
z.S = hsv.S + ((hsv.S < 50) ? 40 : -40);
z.V = 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.S = hsv.S + ((hsv.S < 50) ? 40 : -40);
z.V = hsv.V + ((hsv.V < 50) ? 40 : -40);
outp.Colors[5] = new HSV(z);
return outp;

Просмотреть файл

@ -10,34 +10,34 @@ namespace ColorBlender.Algorithms
Blend outp = new Blend();
outp.Colors[0] = new HSV(hsv);
var w = MathHelpers.HueToWheel(hsv.h);
var w = MathHelpers.HueToWheel(hsv.H);
HSV z = new HSV
{
h = hsv.h,
s = hsv.s,
v = hsv.v
H = hsv.H,
S = hsv.S,
V = hsv.V
};
z.h = MathHelpers.WheelToHue((w + 150) % 360);
z.s = hsv.s;
z.v = hsv.v;
z.H = MathHelpers.WheelToHue((w + 150) % 360);
z.S = hsv.S;
z.V = hsv.V;
outp.Colors[1] = new HSV(z);
z.h = MathHelpers.WheelToHue((w + 210) % 360);
z.s = hsv.s;
z.v = hsv.v;
z.H = MathHelpers.WheelToHue((w + 210) % 360);
z.S = hsv.S;
z.V = hsv.V;
outp.Colors[2] = new HSV(z);
z.s = 0;
z.v = hsv.s;
z.S = 0;
z.V = hsv.S;
outp.Colors[3] = new HSV(z);
z.s = 0;
z.v = hsv.v;
z.S = 0;
z.V = hsv.V;
outp.Colors[4] = new HSV(z);
z.s = 0;
z.v = (100 - hsv.v);
z.S = 0;
z.V = (100 - hsv.V);
outp.Colors[5] = new HSV(z);
return outp;

Просмотреть файл

@ -10,29 +10,29 @@ namespace ColorBlender.Algorithms
Blend outp = new Blend();
outp.Colors[0] = new HSV(hsv);
var w = MathHelpers.HueToWheel(hsv.h);
var w = MathHelpers.HueToWheel(hsv.H);
HSV z = new HSV
{
h = MathHelpers.WheelToHue((w + 90) % 360),
s = hsv.s,
v = hsv.v
H = MathHelpers.WheelToHue((w + 90) % 360),
S = hsv.S,
V = hsv.V
};
outp.Colors[1] = new HSV(z);
z.h = MathHelpers.WheelToHue((w + 180) % 360);
z.s = hsv.s;
z.v = hsv.v;
z.H = MathHelpers.WheelToHue((w + 180) % 360);
z.S = hsv.S;
z.V = hsv.V;
outp.Colors[2] = new HSV(z);
z.h = MathHelpers.WheelToHue((w + 270) % 360);
z.s = hsv.s;
z.v = hsv.v;
z.H = MathHelpers.WheelToHue((w + 270) % 360);
z.S = hsv.S;
z.V = hsv.V;
outp.Colors[3] = new HSV(z);
z.s = 0;
z.S = 0;
outp.Colors[4] = new HSV(z);
z.v = 100 - z.v;
z.V = 100 - z.V;
outp.Colors[5] = new HSV(z);
return outp;

Просмотреть файл

@ -10,35 +10,35 @@ namespace ColorBlender.Algorithms
Blend outp = new Blend();
outp.Colors[0] = new HSV(hsv);
var w = MathHelpers.HueToWheel(hsv.h);
var w = MathHelpers.HueToWheel(hsv.H);
HSV z = new HSV
{
s = hsv.s,
h = hsv.h,
v = 100 - hsv.v
S = hsv.S,
H = hsv.H,
V = 100 - hsv.V
};
outp.Colors[1] = new HSV(z);
z = new HSV
{
h = MathHelpers.WheelToHue((w + 120) % 360),
s = hsv.s,
v = hsv.v
H = MathHelpers.WheelToHue((w + 120) % 360),
S = hsv.S,
V = hsv.V
};
outp.Colors[2] = new HSV(z);
z.v = 100 - z.v;
z.V = 100 - z.V;
outp.Colors[3] = new HSV(z);
z = new HSV
{
h = MathHelpers.WheelToHue((w + 240) % 360),
s = hsv.s,
v = hsv.v
H = MathHelpers.WheelToHue((w + 240) % 360),
S = hsv.S,
V = hsv.V
};
outp.Colors[4] = new HSV(z);
z.v = 100 - z.v;
z.V = 100 - z.V;
outp.Colors[5] = new HSV(z);
return outp;

Просмотреть файл

@ -1,48 +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;
using ColorBlender.Algorithms;
namespace ColorBlender
{
// Color matching algorithms:
// "classic" ColorMatch 5K Classic
// "colorexplorer" ColorExplorer - "Sweet Spot Offset"
// "singlehue" Single Hue
// "complementary" Complementary
// "splitcomplementary" Split-Complementary
// "analogue" Analogue
// "triadic" Triadic
// "square" Square
// Color matching algorithm. All work is done in HSV color space, because all
// calculations are based on hue, saturation and value of the working color.
// The hue spectrum is divided into sections, are the matching colors are
// calculated differently depending on the hue of the color.
public static class ColorMatch
{
public static Blend Match(HSV hs, string method)
{
switch (method)
{
case "classic":
return new Classic().Match(hs);
case "colorexplorer":
return new ColorExplorer().Match(hs);
case "singlehue":
return new SingleHue().Match(hs);
case "complementary":
return new Complementary().Match(hs);
case "splitcomplementary":
return new SplitComplementary().Match(hs);
case "analogue":
return new Analogue().Match(hs);
case "triadic":
return new Triadic().Match(hs);
case "square":
return new Square().Match(hs);
}
return null;
}
}
}

Просмотреть файл

@ -6,67 +6,67 @@ namespace ColorBlender
{
public class HSV
{
public double h;
public double s;
public double v;
public double H;
public double S;
public double V;
public HSV() { }
public HSV(double h, double s, double v)
{
this.h = h;
this.s = s;
this.v = 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;
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;
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);
HSV hsx = new HSV(this.H, this.S, this.V);
if (hsx.s == 0)
if (hsx.S == 0)
{
rg.r = rg.g = rg.b = Math.Round(hsx.v * 2.55); return (rg);
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;
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));
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;
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);
rg.R = Math.Round(rg.R * 255);
rg.G = Math.Round(rg.G * 255);
rg.B = Math.Round(rg.B * 255);
return rg;
}

Просмотреть файл

@ -6,61 +6,61 @@ namespace ColorBlender
{
public class RGB
{
public double r;
public double g;
public double b;
public double R;
public double G;
public double B;
public RGB() { }
public RGB(double r, double g, double b)
{
this.r = r;
this.g = g;
this.b = 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;
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;
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);
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 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 (v == 0.0) { hs.S = 0; } else { hs.S = 100 * delta / v; }
if (hs.s == 0) { hs.h = 0; }
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; }
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);
hs.H = Math.Round(hs.H);
hs.S = Math.Round(hs.S);
hs.V = Math.Round(value);
return hs;
}

Просмотреть файл

@ -26,9 +26,9 @@ namespace ColorBlenderAvalonia
public static Color ToColor(this RGB rgb)
{
return Color.FromRgb(
(byte)Math.Round(rgb.r),
(byte)Math.Round(rgb.g),
(byte)Math.Round(rgb.b));
(byte)Math.Round(rgb.R),
(byte)Math.Round(rgb.G),
(byte)Math.Round(rgb.B));
}
}
}

Просмотреть файл

@ -12,16 +12,7 @@
<Grid ColumnDefinitions="*,*,*,*,*,*" Grid.Column="0" Grid.Row="0">
<TextBlock Text="Current Blend" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" Margin="5,2,5,2" HorizontalAlignment="Left" VerticalAlignment="Center" />
<TextBlock Text="algorithm:" Grid.Column="2" Grid.Row="0" Grid.ColumnSpan="2" Margin="5,2,5,2" HorizontalAlignment="Right" VerticalAlignment="Center" />
<DropDown x:Name="algorithm" Grid.Column="4" Grid.Row="0" Grid.ColumnSpan="2" SelectedIndex="0">
<DropDownItem Content="classic" />
<DropDownItem Content="colorexplorer" />
<DropDownItem Content="singlehue" />
<DropDownItem Content="complementary" />
<DropDownItem Content="splitcomplementary" />
<DropDownItem Content="analogue" />
<DropDownItem Content="triadic" />
<DropDownItem Content="square" />
</DropDown>
<DropDown x:Name="algorithm" Grid.Column="4" Grid.Row="0" Grid.ColumnSpan="2" Items="{Binding Algorithms}" SelectedItem="{Binding CurrentAlgorithm}"/>
</Grid>
<Grid x:Name="swatches" ColumnDefinitions="*,*,*,*,*,*" Grid.Row="1">
<local:Swatch x:Name="swatch1" Grid.Column="0" Margin="2" />

Просмотреть файл

@ -1,6 +1,9 @@
// 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 System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Shapes;
@ -8,17 +11,12 @@ using Avalonia.Input;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using ColorBlender;
using ColorBlender.Algorithms;
namespace ColorBlenderAvalonia
{
public class MainWindow : Window
{
private RGB rgb;
private HSV hsv;
private Blend z;
private RGB[] vRGB = new RGB[7];
private RGB[] vHSV = new RGB[9];
private bool updatingSliders = false;
private DropDown algorithm;
private Slider sliderR;
private Slider sliderG;
@ -49,16 +47,56 @@ namespace ColorBlenderAvalonia
private Swatch swatch5;
private Swatch swatch6;
private string Algorithm
{
get { return (algorithm.SelectedItem as DropDownItem).Content.ToString(); }
}
private RGB rgb;
private HSV hsv;
private Blend z;
private RGB[] vRGB = new RGB[7];
private RGB[] vHSV = new RGB[9];
private bool updatingSliders = false;
public IList<IAlgorithm> Algorithms { get; set; }
public IAlgorithm CurrentAlgorithm { get; set; }
public MainWindow()
{
this.InitializeComponent();
this.AttachDevTools();
this.InitializeNames();
Algorithms = new ObservableCollection<IAlgorithm>()
{
new Classic(),
new ColorExplorer(),
new SingleHue(),
new Complementary(),
new SplitComplementary(),
new Analogue(),
new Triadic(),
new Square()
};
CurrentAlgorithm = Algorithms.FirstOrDefault();
DataContext = this;
hsv = new HSV(213, 46, 49);
rgb = new RGB(hsv);
z = CurrentAlgorithm.Match(hsv);
UpdateSliderRGB();
UpdateSliderHSV();
UpdateSwatches();
UpdateVariations();
InitializeEventHandlers();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
private void InitializeNames()
{
algorithm = this.FindControl<DropDown>("algorithm");
sliderR = this.FindControl<Slider>("sliderR");
sliderG = this.FindControl<Slider>("sliderG");
@ -88,16 +126,10 @@ namespace ColorBlenderAvalonia
swatch4 = this.FindControl<Swatch>("swatch4");
swatch5 = this.FindControl<Swatch>("swatch5");
swatch6 = this.FindControl<Swatch>("swatch6");
}
hsv = new HSV(213, 46, 49);
rgb = new RGB(hsv);
z = ColorMatch.Match(hsv, Algorithm);
UpdateSliderRGB();
UpdateSliderHSV();
UpdateSwatches();
UpdateVariations();
private void InitializeEventHandlers()
{
sliderR.GetObservable(Slider.ValueProperty).Subscribe(value => SliderRGB_ValueChanged());
sliderG.GetObservable(Slider.ValueProperty).Subscribe(value => SliderRGB_ValueChanged());
sliderB.GetObservable(Slider.ValueProperty).Subscribe(value => SliderRGB_ValueChanged());
@ -112,6 +144,7 @@ namespace ColorBlenderAvalonia
rgbvar5.PointerPressed += Rectangle_PointerPressed;
rgbvar6.PointerPressed += Rectangle_PointerPressed;
rgbvar7.PointerPressed += Rectangle_PointerPressed;
hsvvar1.PointerPressed += Rectangle_PointerPressed;
hsvvar2.PointerPressed += Rectangle_PointerPressed;
hsvvar3.PointerPressed += Rectangle_PointerPressed;
@ -121,23 +154,20 @@ namespace ColorBlenderAvalonia
hsvvar7.PointerPressed += Rectangle_PointerPressed;
hsvvar8.PointerPressed += Rectangle_PointerPressed;
hsvvar9.PointerPressed += Rectangle_PointerPressed;
swatch1.col.PointerPressed += Rectangle_PointerPressed;
swatch2.col.PointerPressed += Rectangle_PointerPressed;
swatch3.col.PointerPressed += Rectangle_PointerPressed;
swatch4.col.PointerPressed += Rectangle_PointerPressed;
swatch5.col.PointerPressed += Rectangle_PointerPressed;
swatch6.col.PointerPressed += Rectangle_PointerPressed;
algorithm.SelectionChanged += Algorithm_SelectionChanged;
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
algorithm.SelectionChanged += Algorithm_SelectionChanged;
}
private void Algorithm_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
z = ColorMatch.Match(hsv, Algorithm);
z = CurrentAlgorithm.Match(hsv);
UpdateSwatches();
UpdateVariations();
}
@ -173,7 +203,7 @@ namespace ColorBlenderAvalonia
UpdateSliderHSV();
updatingSliders = false;
z = ColorMatch.Match(hsv, Algorithm);
z = CurrentAlgorithm.Match(hsv);
UpdateSwatches();
UpdateVariations();
}
@ -190,16 +220,16 @@ namespace ColorBlenderAvalonia
private void UpdateSliderRGB()
{
sliderR.Value = rgb.r;
sliderG.Value = rgb.g;
sliderB.Value = rgb.b;
sliderR.Value = rgb.R;
sliderG.Value = rgb.G;
sliderB.Value = rgb.B;
}
private void UpdateSliderHSV()
{
sliderH.Value = hsv.h;
sliderS.Value = hsv.s;
sliderV.Value = hsv.v;
sliderH.Value = hsv.H;
sliderS.Value = hsv.S;
sliderV.Value = hsv.V;
}
private double AddLimit(double x, double d, double min, double max)
@ -217,13 +247,13 @@ namespace ColorBlenderAvalonia
var rgbobj = new RGB();
var hsvobj = new HSV
{
h = hsv.h,
s = hsv.s,
v = hsv.v
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);
hsvobj.S = AddLimit(hsvobj.S, addsat, 0, 99);
hsvobj.V = AddLimit(hsvobj.V, addval, 0, 99);
rgbobj = hsvobj.ToRGB();
@ -235,13 +265,13 @@ namespace ColorBlenderAvalonia
double vv = 20;
double vw = 10;
vRGB[0] = new RGB(AddLimit(rgb.r, -vw, 0, 255), AddLimit(rgb.g, vv, 0, 255), AddLimit(rgb.b, -vw, 0, 255));
vRGB[1] = new RGB(AddLimit(rgb.r, vw, 0, 255), AddLimit(rgb.g, vw, 0, 255), AddLimit(rgb.b, -vv, 0, 255));
vRGB[2] = new RGB(AddLimit(rgb.r, -vv, 0, 255), AddLimit(rgb.g, vw, 0, 255), AddLimit(rgb.b, vw, 0, 255));
vRGB[3] = new RGB(rgb.r, rgb.g, rgb.b);
vRGB[4] = new RGB(AddLimit(rgb.r, vv, 0, 255), AddLimit(rgb.g, -vw, 0, 255), AddLimit(rgb.b, -vw, 0, 255));
vRGB[5] = new RGB(AddLimit(rgb.r, -vw, 0, 255), AddLimit(rgb.g, -vw, 0, 255), AddLimit(rgb.b, vv, 0, 255));
vRGB[6] = new RGB(AddLimit(rgb.r, vw, 0, 255), AddLimit(rgb.g, -vv, 0, 255), AddLimit(rgb.b, vw, 0, 255));
vRGB[0] = new RGB(AddLimit(rgb.R, -vw, 0, 255), AddLimit(rgb.G, vv, 0, 255), AddLimit(rgb.B, -vw, 0, 255));
vRGB[1] = new RGB(AddLimit(rgb.R, vw, 0, 255), AddLimit(rgb.G, vw, 0, 255), AddLimit(rgb.B, -vv, 0, 255));
vRGB[2] = new RGB(AddLimit(rgb.R, -vv, 0, 255), AddLimit(rgb.G, vw, 0, 255), AddLimit(rgb.B, vw, 0, 255));
vRGB[3] = new RGB(rgb.R, rgb.G, rgb.B);
vRGB[4] = new RGB(AddLimit(rgb.R, vv, 0, 255), AddLimit(rgb.G, -vw, 0, 255), AddLimit(rgb.B, -vw, 0, 255));
vRGB[5] = new RGB(AddLimit(rgb.R, -vw, 0, 255), AddLimit(rgb.G, -vw, 0, 255), AddLimit(rgb.B, vv, 0, 255));
vRGB[6] = new RGB(AddLimit(rgb.R, vw, 0, 255), AddLimit(rgb.G, -vv, 0, 255), AddLimit(rgb.B, vw, 0, 255));
}
private void UpdateVariationsHSV()
@ -285,9 +315,9 @@ namespace ColorBlenderAvalonia
private void HandleSliderValueChangedRGB()
{
rgb.r = sliderR.Value;
rgb.g = sliderG.Value;
rgb.b = sliderB.Value;
rgb.R = sliderR.Value;
rgb.G = sliderG.Value;
rgb.B = sliderB.Value;
hsv = rgb.ToHSV();
rgb = hsv.ToRGB();
@ -296,16 +326,16 @@ namespace ColorBlenderAvalonia
UpdateSliderHSV();
updatingSliders = false;
z = ColorMatch.Match(hsv, Algorithm);
z = CurrentAlgorithm.Match(hsv);
UpdateSwatches();
UpdateVariations();
}
private void HandleSliderValueChangedHSV()
{
hsv.h = sliderH.Value;
hsv.s = sliderS.Value;
hsv.v = sliderV.Value;
hsv.H = sliderH.Value;
hsv.S = sliderS.Value;
hsv.V = sliderV.Value;
rgb = hsv.ToRGB();
@ -313,7 +343,7 @@ namespace ColorBlenderAvalonia
UpdateSliderRGB();
updatingSliders = false;
z = ColorMatch.Match(hsv, Algorithm);
z = CurrentAlgorithm.Match(hsv);
UpdateSwatches();
UpdateVariations();
}

Просмотреть файл

@ -26,9 +26,9 @@ namespace ColorBlenderWPF
public static Color ToColor(this RGB rgb)
{
return Color.FromRgb(
(byte)Math.Round(rgb.r),
(byte)Math.Round(rgb.g),
(byte)Math.Round(rgb.b));
(byte)Math.Round(rgb.R),
(byte)Math.Round(rgb.G),
(byte)Math.Round(rgb.B));
}
}
}

Просмотреть файл

@ -30,16 +30,7 @@
</Grid.ColumnDefinitions>
<TextBlock Text="Current Blend" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" Margin="5,2,5,2" HorizontalAlignment="Left" VerticalAlignment="Center" />
<TextBlock Text="algorithm:" Grid.Column="2" Grid.Row="0" Grid.ColumnSpan="2" Margin="5,2,5,2" HorizontalAlignment="Right" VerticalAlignment="Center" />
<ComboBox x:Name="algorithm" Grid.Column="4" Grid.Row="0" Grid.ColumnSpan="2" SelectedIndex="0">
<ComboBoxItem Content="classic" />
<ComboBoxItem Content="colorexplorer" />
<ComboBoxItem Content="singlehue" />
<ComboBoxItem Content="complementary" />
<ComboBoxItem Content="splitcomplementary" />
<ComboBoxItem Content="analogue" />
<ComboBoxItem Content="triadic" />
<ComboBoxItem Content="square" />
</ComboBox>
<ComboBox x:Name="algorithm" Grid.Column="4" Grid.Row="0" Grid.ColumnSpan="2" ItemsSource="{Binding Algorithms}" SelectedItem="{Binding CurrentAlgorithm}"/>
</Grid>
<Grid x:Name="swatches" Grid.Row="1">
<Grid.ColumnDefinitions>

Просмотреть файл

@ -1,11 +1,15 @@
// 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.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using ColorBlender;
using ColorBlender.Algorithms;
namespace ColorBlenderWPF
{
@ -13,35 +17,54 @@ namespace ColorBlenderWPF
{
private RGB rgb;
private HSV hsv;
private Blend z;
private Blend blend;
private RGB[] vRGB = new RGB[7];
private RGB[] vHSV = new RGB[9];
private bool updatingSliders = false;
private string Algorithm
{
get { return (algorithm.SelectedItem as ComboBoxItem).Content.ToString(); }
}
public IList<IAlgorithm> Algorithms { get; set; }
public IAlgorithm CurrentAlgorithm { get; set; }
public MainWindow()
{
InitializeComponent();
Algorithms = new ObservableCollection<IAlgorithm>()
{
new Classic(),
new ColorExplorer(),
new SingleHue(),
new Complementary(),
new SplitComplementary(),
new Analogue(),
new Triadic(),
new Square()
};
CurrentAlgorithm = Algorithms.FirstOrDefault();
DataContext = this;
hsv = new HSV(213, 46, 49);
rgb = new RGB(hsv);
z = ColorMatch.Match(hsv, Algorithm);
blend = CurrentAlgorithm.Match(hsv);
UpdateSliderRGB();
UpdateSliderHSV();
UpdateSwatches();
UpdateVariations();
InitializeEventHandlers();
}
private void InitializeEventHandlers()
{
sliderR.ValueChanged += SliderRGB_ValueChanged;
sliderG.ValueChanged += SliderRGB_ValueChanged;
sliderB.ValueChanged += SliderRGB_ValueChanged;
sliderH.ValueChanged += SliderHSV_ValueChanged;
sliderS.ValueChanged += SliderHSV_ValueChanged;
sliderV.ValueChanged += SliderHSV_ValueChanged;
rgbvar1.MouseLeftButtonDown += Rectangle_MouseLeftButtonDown;
rgbvar2.MouseLeftButtonDown += Rectangle_MouseLeftButtonDown;
rgbvar3.MouseLeftButtonDown += Rectangle_MouseLeftButtonDown;
@ -49,6 +72,7 @@ namespace ColorBlenderWPF
rgbvar5.MouseLeftButtonDown += Rectangle_MouseLeftButtonDown;
rgbvar6.MouseLeftButtonDown += Rectangle_MouseLeftButtonDown;
rgbvar7.MouseLeftButtonDown += Rectangle_MouseLeftButtonDown;
hsvvar1.MouseLeftButtonDown += Rectangle_MouseLeftButtonDown;
hsvvar2.MouseLeftButtonDown += Rectangle_MouseLeftButtonDown;
hsvvar3.MouseLeftButtonDown += Rectangle_MouseLeftButtonDown;
@ -58,18 +82,20 @@ namespace ColorBlenderWPF
hsvvar7.MouseLeftButtonDown += Rectangle_MouseLeftButtonDown;
hsvvar8.MouseLeftButtonDown += Rectangle_MouseLeftButtonDown;
hsvvar9.MouseLeftButtonDown += Rectangle_MouseLeftButtonDown;
swatch1.col.MouseLeftButtonDown += Rectangle_MouseLeftButtonDown;
swatch2.col.MouseLeftButtonDown += Rectangle_MouseLeftButtonDown;
swatch3.col.MouseLeftButtonDown += Rectangle_MouseLeftButtonDown;
swatch4.col.MouseLeftButtonDown += Rectangle_MouseLeftButtonDown;
swatch5.col.MouseLeftButtonDown += Rectangle_MouseLeftButtonDown;
swatch6.col.MouseLeftButtonDown += Rectangle_MouseLeftButtonDown;
algorithm.SelectionChanged += Algorithm_SelectionChanged;
}
private void Algorithm_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
z = ColorMatch.Match(hsv, Algorithm);
blend = CurrentAlgorithm.Match(hsv);
UpdateSwatches();
UpdateVariations();
}
@ -105,33 +131,33 @@ namespace ColorBlenderWPF
UpdateSliderHSV();
updatingSliders = false;
z = ColorMatch.Match(hsv, Algorithm);
blend = CurrentAlgorithm.Match(hsv);
UpdateSwatches();
UpdateVariations();
}
private void UpdateSwatches()
{
swatch1.col.Fill = new SolidColorBrush(ColorExtensions.ToColor(z.Colors[0]));
swatch2.col.Fill = new SolidColorBrush(ColorExtensions.ToColor(z.Colors[1]));
swatch3.col.Fill = new SolidColorBrush(ColorExtensions.ToColor(z.Colors[2]));
swatch4.col.Fill = new SolidColorBrush(ColorExtensions.ToColor(z.Colors[3]));
swatch5.col.Fill = new SolidColorBrush(ColorExtensions.ToColor(z.Colors[4]));
swatch6.col.Fill = new SolidColorBrush(ColorExtensions.ToColor(z.Colors[5]));
swatch1.col.Fill = new SolidColorBrush(ColorExtensions.ToColor(blend.Colors[0]));
swatch2.col.Fill = new SolidColorBrush(ColorExtensions.ToColor(blend.Colors[1]));
swatch3.col.Fill = new SolidColorBrush(ColorExtensions.ToColor(blend.Colors[2]));
swatch4.col.Fill = new SolidColorBrush(ColorExtensions.ToColor(blend.Colors[3]));
swatch5.col.Fill = new SolidColorBrush(ColorExtensions.ToColor(blend.Colors[4]));
swatch6.col.Fill = new SolidColorBrush(ColorExtensions.ToColor(blend.Colors[5]));
}
private void UpdateSliderRGB()
{
sliderR.Value = rgb.r;
sliderG.Value = rgb.g;
sliderB.Value = rgb.b;
sliderR.Value = rgb.R;
sliderG.Value = rgb.G;
sliderB.Value = rgb.B;
}
private void UpdateSliderHSV()
{
sliderH.Value = hsv.h;
sliderS.Value = hsv.s;
sliderV.Value = hsv.v;
sliderH.Value = hsv.H;
sliderS.Value = hsv.S;
sliderV.Value = hsv.V;
}
private double AddLimit(double x, double d, double min, double max)
@ -149,13 +175,13 @@ namespace ColorBlenderWPF
var rgbobj = new RGB();
var hsvobj = new HSV
{
h = hsv.h,
s = hsv.s,
v = hsv.v
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);
hsvobj.S = AddLimit(hsvobj.S, addsat, 0, 99);
hsvobj.V = AddLimit(hsvobj.V, addval, 0, 99);
rgbobj = hsvobj.ToRGB();
@ -167,13 +193,13 @@ namespace ColorBlenderWPF
double vv = 20;
double vw = 10;
vRGB[0] = new RGB(AddLimit(rgb.r, -vw, 0, 255), AddLimit(rgb.g, vv, 0, 255), AddLimit(rgb.b, -vw, 0, 255));
vRGB[1] = new RGB(AddLimit(rgb.r, vw, 0, 255), AddLimit(rgb.g, vw, 0, 255), AddLimit(rgb.b, -vv, 0, 255));
vRGB[2] = new RGB(AddLimit(rgb.r, -vv, 0, 255), AddLimit(rgb.g, vw, 0, 255), AddLimit(rgb.b, vw, 0, 255));
vRGB[3] = new RGB(rgb.r, rgb.g, rgb.b);
vRGB[4] = new RGB(AddLimit(rgb.r, vv, 0, 255), AddLimit(rgb.g, -vw, 0, 255), AddLimit(rgb.b, -vw, 0, 255));
vRGB[5] = new RGB(AddLimit(rgb.r, -vw, 0, 255), AddLimit(rgb.g, -vw, 0, 255), AddLimit(rgb.b, vv, 0, 255));
vRGB[6] = new RGB(AddLimit(rgb.r, vw, 0, 255), AddLimit(rgb.g, -vv, 0, 255), AddLimit(rgb.b, vw, 0, 255));
vRGB[0] = new RGB(AddLimit(rgb.R, -vw, 0, 255), AddLimit(rgb.G, vv, 0, 255), AddLimit(rgb.B, -vw, 0, 255));
vRGB[1] = new RGB(AddLimit(rgb.R, vw, 0, 255), AddLimit(rgb.G, vw, 0, 255), AddLimit(rgb.B, -vv, 0, 255));
vRGB[2] = new RGB(AddLimit(rgb.R, -vv, 0, 255), AddLimit(rgb.G, vw, 0, 255), AddLimit(rgb.B, vw, 0, 255));
vRGB[3] = new RGB(rgb.R, rgb.G, rgb.B);
vRGB[4] = new RGB(AddLimit(rgb.R, vv, 0, 255), AddLimit(rgb.G, -vw, 0, 255), AddLimit(rgb.B, -vw, 0, 255));
vRGB[5] = new RGB(AddLimit(rgb.R, -vw, 0, 255), AddLimit(rgb.G, -vw, 0, 255), AddLimit(rgb.B, vv, 0, 255));
vRGB[6] = new RGB(AddLimit(rgb.R, vw, 0, 255), AddLimit(rgb.G, -vv, 0, 255), AddLimit(rgb.B, vw, 0, 255));
}
private void UpdateVariationsHSV()
@ -217,9 +243,9 @@ namespace ColorBlenderWPF
private void HandleSliderValueChangedRGB()
{
rgb.r = sliderR.Value;
rgb.g = sliderG.Value;
rgb.b = sliderB.Value;
rgb.R = sliderR.Value;
rgb.G = sliderG.Value;
rgb.B = sliderB.Value;
hsv = rgb.ToHSV();
rgb = hsv.ToRGB();
@ -228,16 +254,16 @@ namespace ColorBlenderWPF
UpdateSliderHSV();
updatingSliders = false;
z = ColorMatch.Match(hsv, Algorithm);
blend = CurrentAlgorithm.Match(hsv);
UpdateSwatches();
UpdateVariations();
}
private void HandleSliderValueChangedHSV()
{
hsv.h = sliderH.Value;
hsv.s = sliderS.Value;
hsv.v = sliderV.Value;
hsv.H = sliderH.Value;
hsv.S = sliderS.Value;
hsv.V = sliderV.Value;
rgb = hsv.ToRGB();
@ -245,7 +271,7 @@ namespace ColorBlenderWPF
UpdateSliderRGB();
updatingSliders = false;
z = ColorMatch.Match(hsv, Algorithm);
blend = CurrentAlgorithm.Match(hsv);
UpdateSwatches();
UpdateVariations();
}

Просмотреть файл

@ -0,0 +1,178 @@
// 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 Xunit;
namespace ColorBlender.UnitTests
{
public class AlgorithmsTests
{
[Fact]
public void Classic_Match()
{
var hsv = new HSV(213, 46, 49);
var algorithm = new Classic();
var actual = algorithm.Match(hsv);
var expected = new Blend()
{
Colors = new[]
{
new HSV(213, 46, 49),
new HSV(213, 46, 79),
new HSV(53, 46, 49),
new HSV(43, 46, 79),
new HSV(0, 0, 51),
new HSV(0, 0, 49)
}
};
Assert.Equal(expected, actual, new BlendEqualityComparer());
}
[Fact]
public void ColorExplorer_Match()
{
var hsv = new HSV(213, 46, 49);
var algorithm = new ColorExplorer();
var actual = algorithm.Match(hsv);
var expected = new Blend()
{
Colors = new[]
{
new HSV(213, 46, 49),
new HSV(213, 14, 64),
new HSV(153, 55, 24),
new HSV(153, 46, 49),
new HSV(153, 0, 99),
new HSV(153, 0, 49)
}
};
Assert.Equal(expected, actual, new BlendEqualityComparer());
}
[Fact]
public void SingleHue_Match()
{
var hsv = new HSV(213, 46, 49);
var algorithm = new SingleHue();
var actual = algorithm.Match(hsv);
var expected = new Blend()
{
Colors = new[]
{
new HSV(213, 46, 49),
new HSV(213, 46, 69),
new HSV(213, 46, 89),
new HSV(213, 66, 49),
new HSV(213, 86, 49),
new HSV(213, 86, 89)
}
};
Assert.Equal(expected, actual, new BlendEqualityComparer());
}
[Fact]
public void Complementary_Match()
{
var hsv = new HSV(213, 46, 49);
var algorithm = new Complementary();
var actual = algorithm.Match(hsv);
var expected = new Blend()
{
Colors = new[]
{
new HSV(213, 46, 49),
new HSV(213, 92, 73.5),
new HSV(47, 46, 49),
new HSV(47, 92, 73.5),
new HSV(0, 0, 49),
new HSV(0, 0, 51)
}
};
Assert.Equal(expected, actual, new BlendEqualityComparer());
}
[Fact]
public void SplitComplementary_Match()
{
var hsv = new HSV(213, 46, 49);
var algorithm = new SplitComplementary();
var actual = algorithm.Match(hsv);
var expected = new Blend()
{
Colors = new[]
{
new HSV(213, 46, 49),
new HSV(27, 46, 49),
new HSV(67, 46, 49),
new HSV(67, 0, 46),
new HSV(67, 0, 49),
new HSV(67, 0, 51)
}
};
Assert.Equal(expected, actual, new BlendEqualityComparer());
}
[Fact]
public void Analogue_Match()
{
var hsv = new HSV(213, 46, 49);
var algorithm = new Analogue();
var actual = algorithm.Match(hsv);
var expected = new Blend()
{
Colors = new[]
{
new HSV(213, 46, 49),
new HSV(253, 46, 49),
new HSV(293, 46, 49),
new HSV(0, 0, 51),
new HSV(0, 0, 64),
new HSV(0, 0, 38)
}
};
Assert.Equal(expected, actual, new BlendEqualityComparer());
}
[Fact]
public void Triadic_Match()
{
var hsv = new HSV(213, 46, 49);
var algorithm = new Triadic();
var actual = algorithm.Match(hsv);
var expected = new Blend()
{
Colors = new[]
{
new HSV(213, 46, 49),
new HSV(213, 46, 51),
new HSV(7, 46, 49),
new HSV(7, 46, 51),
new HSV(87, 46, 49),
new HSV(87, 46, 51)
}
};
Assert.Equal(expected, actual, new BlendEqualityComparer());
}
[Fact]
public void Square_Match()
{
var hsv = new HSV(213, 46, 49);
var algorithm = new Square();
var actual = algorithm.Match(hsv);
var expected = new Blend()
{
Colors = new[]
{
new HSV(213, 46, 49),
new HSV(333, 46, 49),
new HSV(47, 46, 49),
new HSV(107, 46, 49),
new HSV(107, 0, 49),
new HSV(107, 0, 51)
}
};
Assert.Equal(expected, actual, new BlendEqualityComparer());
}
}
}

Просмотреть файл

@ -0,0 +1,36 @@
// 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.Collections.Generic;
namespace ColorBlender.UnitTests
{
internal class BlendEqualityComparer : IEqualityComparer<Blend>
{
public bool Equals(Blend x, Blend y)
{
return x.Colors[0].H == y.Colors[0].H
&& x.Colors[0].S == y.Colors[0].S
&& x.Colors[0].V == y.Colors[0].V
&& x.Colors[1].H == y.Colors[1].H
&& x.Colors[1].S == y.Colors[1].S
&& x.Colors[1].V == y.Colors[1].V
&& x.Colors[2].H == y.Colors[2].H
&& x.Colors[2].S == y.Colors[2].S
&& x.Colors[2].V == y.Colors[2].V
&& x.Colors[3].H == y.Colors[3].H
&& x.Colors[3].S == y.Colors[3].S
&& x.Colors[3].V == y.Colors[3].V
&& x.Colors[4].H == y.Colors[4].H
&& x.Colors[4].S == y.Colors[4].S
&& x.Colors[4].V == y.Colors[4].V
&& x.Colors[5].H == y.Colors[5].H
&& x.Colors[5].S == y.Colors[5].S
&& x.Colors[5].V == y.Colors[5].V;
}
public int GetHashCode(Blend obj)
{
return 0;
}
}
}

Просмотреть файл

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0-preview-20170628-02" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\ColorBlender\ColorBlender.csproj" />
</ItemGroup>
</Project>