Browse Source

Tests included. Having a hard time making the unit test results match any web converter to a high degree. I am using the Colormine coefs, but since their calculations use double and I am using float, I am still in trouble with a few values.

Former-commit-id: e70cd5f9e2ca95e8c7f349fd7eed8669eb64a169
Former-commit-id: 75df1cb3a3c8bf5915cc7d29bf053d9b3b82a42b
Former-commit-id: b0582b9a280ccd32912e14b7df7f99063589b27e
pull/17/head
Rubens Fernandes 10 years ago
parent
commit
cb690286ec
  1. 14
      src/ImageProcessor/Colors/ColorTransforms.cs
  2. 12
      src/ImageProcessor/Colors/Colorspaces/CieLab.cs
  3. 81
      tests/ImageProcessor.Tests/Colors/ColorConversionTests.cs

14
src/ImageProcessor/Colors/ColorTransforms.cs

@ -188,20 +188,20 @@ namespace ImageProcessor
float x = cieLabColor.A / 500F + y;
float z = y - cieLabColor.B / 200F;
float x3 = (float)Math.Pow(x, 3);
float y3 = (float)Math.Pow(y, 3);
float z3 = (float)Math.Pow(z, 3);
float x3 = x * x * x;
float y3 = y * y * y;
float z3 = z * z * z;
y = (y3 > 0.008856F) ? y3 : (y - 16F / 116F) / 7.787F;
x = (x3 > 0.008856F) ? x3 : (x - 16F / 116F) / 7.787F;
z = (z3 > 0.008856F) ? z3 : (z - 16F / 116F) / 7.787F;
// Then XYZ to RGB
float r = (x * 3.240969941904521F) + (y * -1.537383177570093F) + (z * -0.498610760293F);
float g = (x * -0.96924363628087F) + (y * 1.87596750150772F) + (z * 0.041555057407175F);
float b = (x * 0.055630079696993F) + (y * -0.20397695888897F) + (z * 1.056971514242878F);
float r = (x * 3.2406F) + (y * -1.5372F) + (z * -0.4986F);
float g = (x * -0.9689F) + (y * 1.8758F) + (z * 0.0415F);
float b = (x * 0.0557F) + (y * -0.2040F) + (z * 1.0570F);
return Color.InverseCompand(new Color(r, g, b));
return Color.Compand(new Color(r, g, b));
}
/// <summary>

12
src/ImageProcessor/Colors/Colorspaces/CieLab.cs

@ -82,9 +82,9 @@ namespace ImageProcessor
// First convert to CIE XYZ
color = Color.InverseCompand(color.Limited);
float x = (color.R * 0.41239079926595F) + (color.G * 0.35758433938387F) + (color.B * 0.18048078840183F);
float y = (color.R * 0.21263900587151F) + (color.G * 0.71516867876775F) + (color.B * 0.072192315360733F);
float z = (color.R * 0.019330818715591F) + (color.G * 0.11919477979462F) + (color.B * 0.95053215224966F);
float x = (color.R * 0.4124F) + (color.G * 0.3576F) + (color.B * 0.1805F);
float y = (color.R * 0.2126F) + (color.G * 0.7152F) + (color.B * 0.0722F);
float z = (color.R * 0.0193F) + (color.G * 0.1192F) + (color.B * 0.9505F);
x *= 100F;
y *= 100F;
@ -99,9 +99,9 @@ namespace ImageProcessor
y = y > 0.008856 ? (float) Math.Pow(y, 1F / 3F) : (7.787F * y) + (16F / 116F);
z = z > 0.008856 ? (float) Math.Pow(z, 1F / 3F) : (7.787F * z) + (16F / 116F);
float l = (116 * y) - 16;
float a = 500 * (x - y);
float b = 200 * (y - z);
float l = (116F * y) - 16F;
float a = 500F * (x - y);
float b = 200F * (y - z);
return new CieLab(l, a, b);
}

81
tests/ImageProcessor.Tests/Colors/ColorConversionTests.cs

@ -334,5 +334,86 @@ namespace ImageProcessor.Tests
Assert.Equal(color4, (Color)cmyk4);
}
}
/// <summary>
/// Tests the implicit conversion from <see cref="Color"/> to <see cref="CieLab"/>.
/// Comparison values obtained from
/// http://colormine.org/convert/rgb-to-lab
/// http://au.mathworks.com/help/images/ref/rgb2lab.html
/// http://www.colorhexa.com/00ffff
/// L seems to match quite well, A and B tend to drift from the converter results a bit more
/// </summary>
[Fact]
public void ColorToCieLab()
{
// White
Color color = new Color(1, 1, 1);
CieLab cielab = color;
Assert.Equal(100, cielab.L, 1);
Assert.Equal(0, cielab.A, 1);
Assert.Equal(0, cielab.B, 1);
// Black
Color color2 = new Color(0, 0, 0);
CieLab cielab2 = color2;
Assert.Equal(0, cielab2.L, 1);
Assert.Equal(0, cielab2.A, 1);
Assert.Equal(0, cielab2.B, 1);
//// Grey
Color color3 = new Color(128 / 255f, 128 / 255f, 128 / 255f);
CieLab cielab3 = color3;
Assert.Equal(53.6, cielab3.L, 1);
Assert.Equal(0, cielab3.A, 1);
Assert.Equal(0, cielab3.B, 1);
//// Cyan
Color color4 = new Color(0, 1, 1);
CieLab cielab4 = color4;
Assert.Equal(91.1, cielab4.L, 1);
Assert.Equal(-48.1, cielab4.A, 1);
Assert.Equal(-14.1, cielab4.B, 1);
}
/// <summary>
/// Tests the implicit conversion from <see cref="CieLab"/> to <see cref="Color"/>.
/// </summary>
[Fact]
public void CieLabToColor()
{
// Dark moderate pink.
CieLab cielab = new CieLab(36.5492f, 33.3173f, -12.0615f);
Color color = cielab;
Assert.Equal(color.R, 128 / 255f, 1);
Assert.Equal(color.G, 64 / 255f, 2);
Assert.Equal(color.B, 106 / 255f, 1);
// Ochre
CieLab cielab2 = new CieLab(58.1758f, 27.3399f, 56.8240f);
Color color2 = cielab2;
Assert.Equal(color2.R, 204 / 255f, 1);
Assert.Equal(color2.G, 119 / 255f, 2);
Assert.Equal(color2.B, 34 / 255f, 1);
//// White
CieLab cielab3 = new CieLab(0, 0, 0);
Color color3 = cielab3;
Assert.Equal(color3.R, 0f, 1);
Assert.Equal(color3.G, 0f, 1);
Assert.Equal(color3.B, 0f, 1);
//// Check others.
Random random = new Random(0);
for (int i = 0; i < 1000; i++)
{
Color color4 = new Color(random.Next(1), random.Next(1), random.Next(1));
CieLab cielab4 = color4;
Assert.Equal(color4, (Color)cielab4);
}
}
}
}

Loading…
Cancel
Save