Skip to content

Commit

Permalink
Merge branch 'release/v0.3.0.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
Mogy committed Apr 14, 2017
2 parents 667b77c + 461f90d commit 2cd9616
Show file tree
Hide file tree
Showing 10 changed files with 948 additions and 76 deletions.
10 changes: 10 additions & 0 deletions BeadsImageConverter.csproj
Expand Up @@ -55,7 +55,14 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Bead.cs" />
<Compile Include="CIEDE2K.cs" />
<Compile Include="CIELAB.cs" />
<Compile Include="FormImages.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="FormImages.Designer.cs">
<DependentUpon>FormImages.cs</DependentUpon>
</Compile>
<Compile Include="FormMain.cs">
<SubType>Form</SubType>
</Compile>
Expand All @@ -64,6 +71,9 @@
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="FormImages.resx">
<DependentUpon>FormImages.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="FormMain.resx">
<DependentUpon>FormMain.cs</DependentUpon>
</EmbeddedResource>
Expand Down
118 changes: 118 additions & 0 deletions CIEDE2K.cs
@@ -0,0 +1,118 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BeadsImageConverter
{
class CIEDE2K
{
private static readonly double KL = 1d;
private static readonly double KC = 1d;
private static readonly double KH = 1d;
private static readonly double Max = Diff(CIELAB.White, CIELAB.Black);

internal static double Pow2(double a) { return a * a; }

internal static double Pow7(double a) { return a * a * a * a * a * a * a; }

internal static double Hypot(double a, double b) { return Math.Sqrt(Pow2(a) + Pow2(b)); }

internal static double Deg2Rad(double deg) { return deg * Math.PI / 180; }

internal static double Rad2Deg(double rad) { return rad * 180 / Math.PI; }

public static double Diff(CIELAB src, CIELAB dst)
{
double c1 = Hypot(src.A, src.B);
double c2 = Hypot(dst.A, dst.B);

double cp7 = Pow7((c1 + c2) / 2);
double tf7 = Pow7(25);

double G = 1 - Math.Sqrt(cp7 / (cp7 + tf7));
double ap1 = src.A + (src.A / 2d) * G;
double ap2 = dst.A + (dst.A / 2d) * G;

double cp1 = Hypot(ap1,src.B);
double cp2 = Hypot(ap2,dst.B);

double hp1 = (Rad2Deg(Math.Atan2(src.B, ap1)) + 360d) % 360d;
double hp2 = (Rad2Deg(Math.Atan2(dst.B, ap2)) + 360d) % 360d;
double h_bar = Math.Abs(hp1 - hp2);

double dLp = dst.L - src.L;
double dCp = cp2 - cp1;
double dHp;
if (cp1 * cp2 == 0) dHp = 0;
else
{
if (h_bar <= 180d)
{
dHp = hp2 - hp1;
}
else if (hp2 <= hp1)
{
dHp = hp2 - hp1 + 360.0;
}
else
{
dHp = hp2 - hp1 - 360.0;
}
}
dHp = 2 * Math.Sqrt(cp1 * cp2) * Math.Sin(Deg2Rad(dHp) / 2);

double aLp = Pow2((src.L + dst.L) / 2d - 50);
double aCp = (cp1 + cp2) / 2d;
double aHp;
if (cp1 * cp2 == 0) aHp = 0;
else
{
if (h_bar <= 180d)
{
aHp = (hp1 + hp2) / 2;
}
else if ((hp1 + hp2) < 360d)
{
aHp = (hp1 + hp2 + 360d) / 2;
}
else
{
aHp = (hp1 + hp2 - 360d) / 2;
}
}

double T = 1
- 0.17 * Math.Cos(Deg2Rad(aHp - 30))
+ 0.24 * Math.Cos(Deg2Rad(aHp * 2))
+ 0.32 * Math.Cos(Deg2Rad(aHp * 3 + 6))
- 0.2 * Math.Cos(Deg2Rad(aHp * 4 - 63));


double SL = 1 + ((0.015d * aLp) / Math.Sqrt(20 + aLp));
double SC = 1 + 0.045d * aCp;
double SH = 1 + 0.015 * aCp * T;

double aCp7 = Pow7(aCp);
double RT = -2d * Math.Sqrt(aCp7 / (aCp7 + tf7)) * Math.Sin(Deg2Rad(60d * Math.Exp(-Pow2((aHp - 275d) / 25d))));

double deltaLp = dLp / (SL * KL);
double deltaCp = dCp / (SC * KC);
double deltaHp = dHp / (SH * KH);

return Math.Sqrt(Pow2(deltaLp) + Pow2(deltaCp) + Pow2(deltaHp) + RT * deltaCp * deltaHp);
}

public static double Difference(Color src, Color dst)
{
return Difference(CIELAB.FromColor(src), CIELAB.FromColor(dst));
}

public static double Difference(CIELAB src, CIELAB dst)
{
return Diff(src, dst) / Max;
}
}
}
23 changes: 14 additions & 9 deletions CIELAB.cs
Expand Up @@ -15,17 +15,17 @@ public class CIELAB
public static readonly CIELAB Black = FromColor(Color.Black);
private static readonly double Max = Diff(White, Black);

public readonly int L;
public readonly int A;
public readonly int B;
public readonly double L;
public readonly double A;
public readonly double B;

private static int[] CreateGammaTable()
{
int[] table = new int[256];
for (int i = 0; i < 256; i++)
{
double value = (double)i / 255.0;
table[i] = (int)(((value > 0.04045) ? Math.Pow((value + 0.055) / 1.055, 2.4) : (value / 12.92)) * 100000.0);
double d = i / 255d;
table[i] = (int)(((d > 0.04045) ? Math.Pow((d + 0.055) / 1.055, 2.4) : (d / 12.92)) * 100000d);
}
return table;
}
Expand All @@ -35,8 +35,8 @@ private static int[] CreateLabTable()
int[] table = new int[100001];
for (int i = 0; i < table.Count<int>(); i++)
{
double value = (double)i / 100001.0;
table[i] = (int)(((value > 0.008856) ? Math.Pow(value, 0.33333333333333331) : (7.787 * value + 0.13793103448275862)) * 1000000.0);
double d = i / 100001d;
table[i] = (int)(((d > 0.008856) ? Math.Pow(d, 1d / 3d) : (7.787 * d + 4d / 29d)) * 1000000d);
}
return table;
}
Expand Down Expand Up @@ -72,15 +72,20 @@ public static CIELAB FromColor(Color color)
int A = 500 * (x - y);
int B = 200 * (y - z);

return new CIELAB(L, A, B);
return new CIELAB(L / 1000000d, A / 1000000d, B / 1000000d);
}

public static double Difference(Color src, Color dst)
{
return Difference(FromColor(src), FromColor(dst));
}

public static double Difference(CIELAB src, CIELAB dst)
{
return Diff(src, dst) / Max;
}

public CIELAB(int l, int a, int b)
public CIELAB(double l, double a, double b)
{
this.L = l;
this.A = a;
Expand Down

0 comments on commit 2cd9616

Please sign in to comment.