mirror of https://github.com/SixLabors/ImageSharp
22 changed files with 829 additions and 39 deletions
@ -0,0 +1,85 @@ |
|||
// <copyright file="ColorSpaceConverter.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Colors.Spaces.Conversion |
|||
{ |
|||
using ImageSharp.Colors.Spaces.Conversion.Implementation.HunterLab; |
|||
|
|||
/// <summary>
|
|||
/// Converts between color spaces ensuring that the color is adapted using chromatic adaptation.
|
|||
/// </summary>
|
|||
public partial class ColorSpaceConverter |
|||
{ |
|||
/// <summary>
|
|||
/// Converts a <see cref="CieXyz"/> into a <see cref="HunterLab"/>
|
|||
/// </summary>
|
|||
/// <param name="color">The color to convert.</param>
|
|||
/// <returns>The <see cref="HunterLab"/></returns>
|
|||
public HunterLab ToHunterLab(CieXyz color) |
|||
{ |
|||
Guard.NotNull(color, nameof(color)); |
|||
|
|||
// Adaptation
|
|||
CieXyz adapted = !this.WhitePoint.Equals(this.TargetHunterLabWhitePoint) && this.IsChromaticAdaptationPerformed |
|||
? this.ChromaticAdaptation.Transform(color, this.WhitePoint, this.TargetHunterLabWhitePoint) |
|||
: color; |
|||
|
|||
// Conversion
|
|||
return new CieXyzToHunterLabConverter(this.TargetHunterLabWhitePoint).Convert(adapted); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Converts a <see cref="Rgb"/> into a <see cref="HunterLab"/>
|
|||
/// </summary>
|
|||
/// <param name="color">The color to convert.</param>
|
|||
/// <returns>The <see cref="HunterLab"/></returns>
|
|||
public HunterLab ToHunterLab(Rgb color) |
|||
{ |
|||
Guard.NotNull(color, nameof(color)); |
|||
|
|||
CieXyz xyzColor = this.ToCieXyz(color); |
|||
return this.ToHunterLab(xyzColor); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Converts a <see cref="LinearRgb"/> into a <see cref="HunterLab"/>
|
|||
/// </summary>
|
|||
/// <param name="color">The color to convert.</param>
|
|||
/// <returns>The <see cref="HunterLab"/></returns>
|
|||
public HunterLab ToHunterLab(LinearRgb color) |
|||
{ |
|||
Guard.NotNull(color, nameof(color)); |
|||
|
|||
CieXyz xyzColor = this.ToCieXyz(color); |
|||
return this.ToHunterLab(xyzColor); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Converts a <see cref="CieLab"/> into a <see cref="HunterLab"/>
|
|||
/// </summary>
|
|||
/// <param name="color">The color to convert.</param>
|
|||
/// <returns>The <see cref="HunterLab"/></returns>
|
|||
public HunterLab ToHunterLab(CieLab color) |
|||
{ |
|||
Guard.NotNull(color, nameof(color)); |
|||
|
|||
CieXyz xyzColor = this.ToCieXyz(color); |
|||
return this.ToHunterLab(xyzColor); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Converts a <see cref="Lms"/> into a <see cref="HunterLab"/>
|
|||
/// </summary>
|
|||
/// <param name="color">The color to convert.</param>
|
|||
/// <returns>The <see cref="HunterLab"/></returns>
|
|||
public HunterLab ToHunterLab(Lms color) |
|||
{ |
|||
Guard.NotNull(color, nameof(color)); |
|||
|
|||
CieXyz xyzColor = this.ToCieXyz(color); |
|||
return this.ToHunterLab(xyzColor); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,51 @@ |
|||
// <copyright file="CieXyzAndHunterLabConverterBase.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Colors.Spaces.Conversion.Implementation.HunterLab |
|||
{ |
|||
using System.Runtime.CompilerServices; |
|||
|
|||
/// <summary>
|
|||
/// The base class for converting between <see cref="HunterLab"/> and <see cref="CieXyz"/> color spaces.
|
|||
/// </summary>
|
|||
internal abstract class CieXyzAndHunterLabConverterBase |
|||
{ |
|||
/// <summary>
|
|||
/// Returns the Ka coefficient that depends upon the whitepoint illuminant.
|
|||
/// </summary>
|
|||
/// <param name="whitePoint">The whitepoint</param>
|
|||
/// <returns>The <see cref="float"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static float ComputeKa(CieXyz whitePoint) |
|||
{ |
|||
DebugGuard.NotNull(whitePoint, nameof(whitePoint)); |
|||
|
|||
if (whitePoint.Equals(Illuminants.C)) |
|||
{ |
|||
return 175; |
|||
} |
|||
|
|||
return 100 * (175 / 198.04F) * (whitePoint.X + whitePoint.Y); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Returns the Kb coefficient that depends upon the whitepoint illuminant.
|
|||
/// </summary>
|
|||
/// <param name="whitePoint">The whitepoint</param>
|
|||
/// <returns>The <see cref="float"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static float ComputeKb(CieXyz whitePoint) |
|||
{ |
|||
DebugGuard.NotNull(whitePoint, nameof(whitePoint)); |
|||
|
|||
if (whitePoint == Illuminants.C) |
|||
{ |
|||
return 70; |
|||
} |
|||
|
|||
return 100 * (70 / 218.11F) * (whitePoint.Y + whitePoint.Z); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,66 @@ |
|||
// <copyright file="CieXyzToHunterLabConverter.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Colors.Spaces.Conversion.Implementation.HunterLab |
|||
{ |
|||
using HunterLab = ImageSharp.Colors.Spaces.HunterLab; |
|||
|
|||
/// <summary>
|
|||
/// Color converter between CieXyz and HunterLab
|
|||
/// </summary>
|
|||
internal class CieXyzToHunterLabConverter : CieXyzAndHunterLabConverterBase, IColorConversion<CieXyz, HunterLab> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="CieXyzToHunterLabConverter"/> class.
|
|||
/// </summary>
|
|||
public CieXyzToHunterLabConverter() |
|||
: this(HunterLab.DefaultWhitePoint) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="CieXyzToHunterLabConverter"/> class.
|
|||
/// </summary>
|
|||
/// <param name="labWhitePoint">The hunter Lab white point.</param>
|
|||
public CieXyzToHunterLabConverter(CieXyz labWhitePoint) |
|||
{ |
|||
this.HunterLabWhitePoint = labWhitePoint; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the target reference white. When not set, <see cref="HunterLab.DefaultWhitePoint"/> is used.
|
|||
/// </summary>
|
|||
public CieXyz HunterLabWhitePoint { get; } |
|||
|
|||
/// <inheritdoc/>
|
|||
public HunterLab Convert(CieXyz input) |
|||
{ |
|||
DebugGuard.NotNull(input, nameof(input)); |
|||
|
|||
// Conversion algorithm described here: http://en.wikipedia.org/wiki/Lab_color_space#Hunter_Lab
|
|||
float x = input.X, y = input.Y, z = input.Z; |
|||
float xn = this.HunterLabWhitePoint.X, yn = this.HunterLabWhitePoint.Y, zn = this.HunterLabWhitePoint.Z; |
|||
|
|||
float ka = ComputeKa(this.HunterLabWhitePoint); |
|||
float kb = ComputeKb(this.HunterLabWhitePoint); |
|||
|
|||
float l = 100 * MathF.Sqrt(y / yn); |
|||
float a = ka * (((x / xn) - (y / yn)) / MathF.Sqrt(y / yn)); |
|||
float b = kb * (((y / yn) - (z / zn)) / MathF.Sqrt(y / yn)); |
|||
|
|||
if (float.IsNaN(a)) |
|||
{ |
|||
a = 0; |
|||
} |
|||
|
|||
if (float.IsNaN(b)) |
|||
{ |
|||
b = 0; |
|||
} |
|||
|
|||
return new HunterLab(l, a, b, this.HunterLabWhitePoint); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
// <copyright file="HunterLabToCieXyzConverter.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Colors.Spaces.Conversion.Implementation.HunterLab |
|||
{ |
|||
using HunterLab = ImageSharp.Colors.Spaces.HunterLab; |
|||
|
|||
/// <summary>
|
|||
/// Color converter between HunterLab and CieXyz
|
|||
/// </summary>
|
|||
internal class HunterLabToCieXyzConverter : CieXyzAndHunterLabConverterBase, IColorConversion<HunterLab, CieXyz> |
|||
{ |
|||
/// <inheritdoc/>
|
|||
public CieXyz Convert(HunterLab input) |
|||
{ |
|||
DebugGuard.NotNull(input, nameof(input)); |
|||
|
|||
// Conversion algorithm described here: http://en.wikipedia.org/wiki/Lab_color_space#Hunter_Lab
|
|||
float l = input.L, a = input.A, b = input.B; |
|||
float xn = input.WhitePoint.X, yn = input.WhitePoint.Y, zn = input.WhitePoint.Z; |
|||
|
|||
float ka = ComputeKa(input.WhitePoint); |
|||
float kb = ComputeKb(input.WhitePoint); |
|||
|
|||
float y = MathF.Pow(l / 100F, 2) * yn; |
|||
float x = (((a / ka) * MathF.Sqrt(y / yn)) + (y / yn)) * xn; |
|||
float z = (((b / kb) * MathF.Sqrt(y / yn)) - (y / yn)) * (-zn); |
|||
|
|||
return new CieXyz(x, y, z); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,190 @@ |
|||
// <copyright file="HunterLab.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Colors.Spaces |
|||
{ |
|||
using System; |
|||
using System.ComponentModel; |
|||
using System.Numerics; |
|||
|
|||
/// <summary>
|
|||
/// Represents an Hunter LAB color.
|
|||
/// <see href="https://en.wikipedia.org/wiki/Lab_color_space"/>
|
|||
/// </summary>
|
|||
public struct HunterLab : IColorVector, IEquatable<HunterLab>, IAlmostEquatable<HunterLab, float> |
|||
{ |
|||
/// <summary>
|
|||
/// D50 standard illuminant.
|
|||
/// Used when reference white is not specified explicitly.
|
|||
/// </summary>
|
|||
public static readonly CieXyz DefaultWhitePoint = Illuminants.C; |
|||
|
|||
/// <summary>
|
|||
/// Represents a <see cref="HunterLab"/> that has L, A, B values set to zero.
|
|||
/// </summary>
|
|||
public static readonly HunterLab Empty = default(HunterLab); |
|||
|
|||
/// <summary>
|
|||
/// The backing vector for SIMD support.
|
|||
/// </summary>
|
|||
private readonly Vector3 backingVector; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="HunterLab"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="l">The lightness dimension.</param>
|
|||
/// <param name="a">The a (green - magenta) component.</param>
|
|||
/// <param name="b">The b (blue - yellow) component.</param>
|
|||
/// <remarks>Uses <see cref="DefaultWhitePoint"/> as white point.</remarks>
|
|||
public HunterLab(float l, float a, float b) |
|||
: this(new Vector3(l, a, b), DefaultWhitePoint) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="HunterLab"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="l">The lightness dimension.</param>
|
|||
/// <param name="a">The a (green - magenta) component.</param>
|
|||
/// <param name="b">The b (blue - yellow) component.</param>
|
|||
/// <param name="whitePoint">The reference white point. <see cref="Illuminants"/></param>
|
|||
public HunterLab(float l, float a, float b, CieXyz whitePoint) |
|||
: this(new Vector3(l, a, b), whitePoint) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="HunterLab"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="vector">The vector representing the l, a, b components.</param>
|
|||
/// <remarks>Uses <see cref="DefaultWhitePoint"/> as white point.</remarks>
|
|||
public HunterLab(Vector3 vector) |
|||
: this(vector, DefaultWhitePoint) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="HunterLab"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="vector">The vector representing the l a b components.</param>
|
|||
/// <param name="whitePoint">The reference white point. <see cref="Illuminants"/></param>
|
|||
public HunterLab(Vector3 vector, CieXyz whitePoint) |
|||
: this() |
|||
{ |
|||
this.backingVector = vector; |
|||
this.WhitePoint = whitePoint; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the reference white point of this color
|
|||
/// </summary>
|
|||
public CieXyz WhitePoint { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the lightness dimension.
|
|||
/// <remarks>A value ranging between 0 (black), 100 (diffuse white) or higher (specular white).</remarks>
|
|||
/// </summary>
|
|||
public float L => this.backingVector.X; |
|||
|
|||
/// <summary>
|
|||
/// Gets the a color component.
|
|||
/// <remarks>A value ranging from -100 to 100. Negative is green, positive magenta.</remarks>
|
|||
/// </summary>
|
|||
public float A => this.backingVector.Y; |
|||
|
|||
/// <summary>
|
|||
/// Gets the b color component.
|
|||
/// <remarks>A value ranging from -100 to 100. Negative is blue, positive is yellow</remarks>
|
|||
/// </summary>
|
|||
public float B => this.backingVector.Z; |
|||
|
|||
/// <summary>
|
|||
/// Gets a value indicating whether this <see cref="HunterLab"/> is empty.
|
|||
/// </summary>
|
|||
[EditorBrowsable(EditorBrowsableState.Never)] |
|||
public bool IsEmpty => this.Equals(Empty); |
|||
|
|||
/// <inheritdoc />
|
|||
public Vector3 Vector => this.backingVector; |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="HunterLab"/> objects for equality.
|
|||
/// </summary>
|
|||
/// <param name="left">
|
|||
/// The <see cref="HunterLab"/> on the left side of the operand.
|
|||
/// </param>
|
|||
/// <param name="right">
|
|||
/// The <see cref="HunterLab"/> on the right side of the operand.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// True if the current left is equal to the <paramref name="right"/> parameter; otherwise, false.
|
|||
/// </returns>
|
|||
public static bool operator ==(HunterLab left, HunterLab right) |
|||
{ |
|||
return left.Equals(right); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="HunterLab"/> objects for inequality
|
|||
/// </summary>
|
|||
/// <param name="left">
|
|||
/// The <see cref="HunterLab"/> on the left side of the operand.
|
|||
/// </param>
|
|||
/// <param name="right">
|
|||
/// The <see cref="HunterLab"/> on the right side of the operand.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// True if the current left is unequal to the <paramref name="right"/> parameter; otherwise, false.
|
|||
/// </returns>
|
|||
public static bool operator !=(HunterLab left, HunterLab right) |
|||
{ |
|||
return !left.Equals(right); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override int GetHashCode() |
|||
{ |
|||
return this.backingVector.GetHashCode(); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override string ToString() |
|||
{ |
|||
if (this.IsEmpty) |
|||
{ |
|||
return "HunterLab [Empty]"; |
|||
} |
|||
|
|||
return $"HunterLab [ L={this.L:#0.##}, A={this.A:#0.##}, B={this.B:#0.##}]"; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override bool Equals(object obj) |
|||
{ |
|||
if (obj is HunterLab) |
|||
{ |
|||
return this.Equals((HunterLab)obj); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public bool Equals(HunterLab other) |
|||
{ |
|||
return this.backingVector.Equals(other.backingVector); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public bool AlmostEquals(HunterLab other, float precision) |
|||
{ |
|||
Vector3 result = Vector3.Abs(this.backingVector - other.backingVector); |
|||
|
|||
return result.X <= precision |
|||
&& result.Y <= precision |
|||
&& result.Z <= precision; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
namespace ImageSharp.Benchmarks.Color |
|||
{ |
|||
using BenchmarkDotNet.Attributes; |
|||
|
|||
using Colourful; |
|||
using Colourful.Conversion; |
|||
|
|||
using ImageSharp.Colors.Spaces; |
|||
using ImageSharp.Colors.Spaces.Conversion; |
|||
|
|||
public class ColorspaceCieXyzToCieLabConvert |
|||
{ |
|||
private static readonly CieXyz CieXyz = new CieXyz(0.95047F, 1, 1.08883F); |
|||
|
|||
private static readonly XYZColor XYZColor = new XYZColor(0.95047, 1, 1.08883); |
|||
|
|||
private static readonly ColorSpaceConverter ColorSpaceConverter = new ColorSpaceConverter(); |
|||
|
|||
private static readonly ColourfulConverter ColourfulConverter = new ColourfulConverter(); |
|||
|
|||
|
|||
[Benchmark(Baseline = true, Description = "Colourful Convert")] |
|||
public LabColor ColourfulConvert() |
|||
{ |
|||
return ColourfulConverter.ToLab(XYZColor); |
|||
} |
|||
|
|||
[Benchmark(Description = "ImageSharp Convert")] |
|||
public CieLab ColorSpaceConvert() |
|||
{ |
|||
return ColorSpaceConverter.ToCieLab(CieXyz); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
namespace ImageSharp.Benchmarks.Color |
|||
{ |
|||
using BenchmarkDotNet.Attributes; |
|||
|
|||
using Colourful; |
|||
using Colourful.Conversion; |
|||
|
|||
using ImageSharp.Colors.Spaces; |
|||
|
|||
using ColorSpaceConverter = ImageSharp.Colors.Spaces.Conversion.ColorSpaceConverter; |
|||
|
|||
public class ColorspaceCieXyzToHunterLabConvert |
|||
{ |
|||
private static readonly CieXyz CieXyz = new CieXyz(0.95047F, 1, 1.08883F); |
|||
|
|||
private static readonly XYZColor XYZColor = new XYZColor(0.95047, 1, 1.08883); |
|||
|
|||
private static readonly ColorSpaceConverter ColorSpaceConverter = new ColorSpaceConverter(); |
|||
|
|||
private static readonly ColourfulConverter ColourfulConverter = new ColourfulConverter(); |
|||
|
|||
|
|||
[Benchmark(Baseline = true, Description = "Colourful Convert")] |
|||
public HunterLabColor ColourfulConvert() |
|||
{ |
|||
return ColourfulConverter.ToHunterLab(XYZColor); |
|||
} |
|||
|
|||
[Benchmark(Description = "ImageSharp Convert")] |
|||
public HunterLab ColorSpaceConvert() |
|||
{ |
|||
return ColorSpaceConverter.ToHunterLab(CieXyz); |
|||
} |
|||
} |
|||
} |
|||
@ -1,6 +0,0 @@ |
|||
<?xml version="1.0" encoding="utf-8" ?> |
|||
<configuration> |
|||
<appSettings> |
|||
<add key="xunit.methodDisplay" value="method"/> |
|||
</appSettings> |
|||
</configuration> |
|||
@ -0,0 +1,73 @@ |
|||
namespace ImageSharp.Tests |
|||
{ |
|||
using System.Collections.Generic; |
|||
using ImageSharp.Colors.Spaces; |
|||
using ImageSharp.Colors.Spaces.Conversion; |
|||
|
|||
using Xunit; |
|||
|
|||
/// <summary>
|
|||
/// Tests <see cref="CieXyz"/>-<see cref="CieLab"/> conversions.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// Test data generated using:
|
|||
/// http://www.brucelindbloom.com/index.html?ColorCalculator.html
|
|||
/// </remarks>
|
|||
public class CieXyzAndCieLabConversionTest |
|||
{ |
|||
private static readonly IEqualityComparer<float> FloatComparerLabPrecision = new ApproximateFloatComparer(4); |
|||
private static readonly IEqualityComparer<float> FloatComparerXyzPrecision = new ApproximateFloatComparer(6); |
|||
|
|||
/// <summary>
|
|||
/// Tests conversion from <see cref="CieLab"/> to <see cref="CieXyz"/> (<see cref="Illuminants.D65"/>).
|
|||
/// </summary>
|
|||
[Theory] |
|||
[InlineData(100, 0, 0, 0.95047, 1, 1.08883)] |
|||
[InlineData(0, 0, 0, 0, 0, 0)] |
|||
[InlineData(0, 431.0345, 0, 0.95047, 0, 0)] |
|||
[InlineData(100, -431.0345, 172.4138, 0, 1, 0)] |
|||
[InlineData(0, 0, -172.4138, 0, 0, 1.08883)] |
|||
[InlineData(45.6398, 39.8753, 35.2091, 0.216938, 0.150041, 0.048850)] |
|||
[InlineData(77.1234, -40.1235, 78.1120, 0.358530, 0.517372, 0.076273)] |
|||
[InlineData(10, -400, 20, 0, 0.011260, 0)] |
|||
public void Convert_Lab_to_XYZ(float l, float a, float b, float x, float y, float z) |
|||
{ |
|||
// Arrange
|
|||
CieLab input = new CieLab(l, a, b, Illuminants.D65); |
|||
ColorSpaceConverter converter = new ColorSpaceConverter { WhitePoint = Illuminants.D65, TargetLabWhitePoint = Illuminants.D65 }; |
|||
|
|||
// Act
|
|||
CieXyz output = converter.ToCieXyz(input); |
|||
|
|||
// Assert
|
|||
Assert.Equal(output.X, x, FloatComparerXyzPrecision); |
|||
Assert.Equal(output.Y, y, FloatComparerXyzPrecision); |
|||
Assert.Equal(output.Z, z, FloatComparerXyzPrecision); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Tests conversion from <see cref="CieXyz"/> (<see cref="Illuminants.D65"/>) to <see cref="CieLab"/>.
|
|||
/// </summary>
|
|||
[Theory] |
|||
[InlineData(0.95047, 1, 1.08883, 100, 0, 0)] |
|||
[InlineData(0, 0, 0, 0, 0, 0)] |
|||
[InlineData(0.95047, 0, 0, 0, 431.0345, 0)] |
|||
[InlineData(0, 1, 0, 100, -431.0345, 172.4138)] |
|||
[InlineData(0, 0, 1.08883, 0, 0, -172.4138)] |
|||
[InlineData(0.216938, 0.150041, 0.048850, 45.6398, 39.8753, 35.2091)] |
|||
public void Convert_XYZ_to_Lab(float x, float y, float z, float l, float a, float b) |
|||
{ |
|||
// Arrange
|
|||
CieXyz input = new CieXyz(x, y, z); |
|||
ColorSpaceConverter converter = new ColorSpaceConverter { WhitePoint = Illuminants.D65, TargetLabWhitePoint = Illuminants.D65 }; |
|||
|
|||
// Act
|
|||
CieLab output = converter.ToCieLab(input); |
|||
|
|||
// Assert
|
|||
Assert.Equal(output.L, l, FloatComparerLabPrecision); |
|||
Assert.Equal(output.A, a, FloatComparerLabPrecision); |
|||
Assert.Equal(output.B, b, FloatComparerLabPrecision); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
{ |
|||
"methodDisplay": "method" |
|||
} |
|||
Loading…
Reference in new issue