Skip to content

Commit

Permalink
add - doc - Added the XYZ color model
Browse files Browse the repository at this point in the history
---

We've added a brand new color model: XYZ!

---

Type: add
Breaking: False
Doc Required: True
Backport Required: False
Part: 1/1
  • Loading branch information
AptiviCEO committed Jul 2, 2024
1 parent 77cb062 commit cf7b15e
Show file tree
Hide file tree
Showing 5 changed files with 377 additions and 1 deletion.
126 changes: 126 additions & 0 deletions Terminaux.Tests/Colors/ColorConversionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,48 @@ public void TestConvertRgbToYuv()
rgb.B.ShouldBe(54);
}

/// <summary>
/// Tests converting an RGB color to XYZ
/// </summary>
[TestMethod]
[Description("Initialization")]
public void TestConvertRgbToXyz()
{
// Create instance
var ColorInstance = new Color(139, 80, 22);

// Check for null
ColorInstance.ShouldNotBeNull();
ColorInstance.PlainSequence.ShouldNotBeNullOrEmpty();
ColorInstance.VTSequenceBackground.ShouldNotBeNullOrEmpty();
ColorInstance.VTSequenceForeground.ShouldNotBeNullOrEmpty();

// Check for property correctness
ColorInstance.PlainSequence.ShouldBe("139;80;22");
ColorInstance.Type.ShouldBe(ColorType.TrueColor);
ColorInstance.VTSequenceBackground.ShouldBe("\u001b[48;2;139;80;22m");
ColorInstance.VTSequenceForeground.ShouldBe("\u001b[38;2;139;80;22m");
ColorInstance.RGB.R.ShouldBe(139);
ColorInstance.RGB.G.ShouldBe(80);
ColorInstance.RGB.B.ShouldBe(22);

// Now, convert to XYZ
var xyz = ConversionTools.ToXyz(ColorInstance.RGB);

// Check for property correctness
xyz.X.ShouldBe(13.660940262318197);
xyz.Y.ShouldBe(11.284216455358383);
xyz.Z.ShouldBe(2.2171176575479863);

// Now, convert back to RGB
var rgb = ConversionTools.ToRgb(xyz);

// Check for property correctness
rgb.R.ShouldBe(138);
rgb.G.ShouldBe(80);
rgb.B.ShouldBe(22);
}

/// <summary>
/// Tests converting an RGB color to CMYK
/// </summary>
Expand Down Expand Up @@ -622,6 +664,48 @@ public void TestGenericConvertRgbToYuv()
rgb.B.ShouldBe(54);
}

/// <summary>
/// Tests converting an RGB color to XYZ
/// </summary>
[TestMethod]
[Description("Initialization")]
public void TestGenericConvertRgbToXyz()
{
// Create instance
var ColorInstance = new Color(139, 80, 22);

// Check for null
ColorInstance.ShouldNotBeNull();
ColorInstance.PlainSequence.ShouldNotBeNullOrEmpty();
ColorInstance.VTSequenceBackground.ShouldNotBeNullOrEmpty();
ColorInstance.VTSequenceForeground.ShouldNotBeNullOrEmpty();

// Check for property correctness
ColorInstance.PlainSequence.ShouldBe("139;80;22");
ColorInstance.Type.ShouldBe(ColorType.TrueColor);
ColorInstance.VTSequenceBackground.ShouldBe("\u001b[48;2;139;80;22m");
ColorInstance.VTSequenceForeground.ShouldBe("\u001b[38;2;139;80;22m");
ColorInstance.RGB.R.ShouldBe(139);
ColorInstance.RGB.G.ShouldBe(80);
ColorInstance.RGB.B.ShouldBe(22);

// Now, convert to XYZ
var xyz = ConversionTools.ConvertFromRgb<Xyz>(ColorInstance.RGB);

// Check for property correctness
xyz.X.ShouldBe(13.660940262318197);
xyz.Y.ShouldBe(11.284216455358383);
xyz.Z.ShouldBe(2.2171176575479863);

// Now, convert back to RGB
var rgb = ConversionTools.ConvertToRgb(xyz);

// Check for property correctness
rgb.R.ShouldBe(138);
rgb.G.ShouldBe(80);
rgb.B.ShouldBe(22);
}

/// <summary>
/// Tests converting an RGB color to CMYK
/// </summary>
Expand Down Expand Up @@ -918,5 +1002,47 @@ public void TestGenericBidirectionalConvertRgbToYuv()
rgb.G.ShouldBe(80);
rgb.B.ShouldBe(54);
}

/// <summary>
/// Tests converting an RGB color to XYZ
/// </summary>
[TestMethod]
[Description("Initialization")]
public void TestGenericBidirectionalConvertRgbToXyz()
{
// Create instance
var ColorInstance = new Color(139, 80, 22);

// Check for null
ColorInstance.ShouldNotBeNull();
ColorInstance.PlainSequence.ShouldNotBeNullOrEmpty();
ColorInstance.VTSequenceBackground.ShouldNotBeNullOrEmpty();
ColorInstance.VTSequenceForeground.ShouldNotBeNullOrEmpty();

// Check for property correctness
ColorInstance.PlainSequence.ShouldBe("139;80;22");
ColorInstance.Type.ShouldBe(ColorType.TrueColor);
ColorInstance.VTSequenceBackground.ShouldBe("\u001b[48;2;139;80;22m");
ColorInstance.VTSequenceForeground.ShouldBe("\u001b[38;2;139;80;22m");
ColorInstance.RGB.R.ShouldBe(139);
ColorInstance.RGB.G.ShouldBe(80);
ColorInstance.RGB.B.ShouldBe(22);

// Now, convert to XYZ
var xyz = ConversionTools.GetConvertedColorModel<RedGreenBlue, Xyz>(ColorInstance.RGB);

// Check for property correctness
xyz.X.ShouldBe(13.660940262318197);
xyz.Y.ShouldBe(11.284216455358383);
xyz.Z.ShouldBe(2.2171176575479863);

// Now, convert back to RGB
var rgb = ConversionTools.GetConvertedColorModel<Xyz, RedGreenBlue>(xyz);

// Check for property correctness
rgb.R.ShouldBe(138);
rgb.G.ShouldBe(80);
rgb.B.ShouldBe(22);
}
}
}
4 changes: 3 additions & 1 deletion Terminaux/Colors/Models/BaseColorModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ public static bool IsSpecifierAndValueValid(string specifier)
RedGreenBlue.IsSpecifierAndValueValid(specifier) ||
RedYellowBlue.IsSpecifierAndValueValid(specifier) ||
LumaInPhaseQuadrature.IsSpecifierAndValueValid(specifier) ||
LumaChromaUv.IsSpecifierAndValueValid(specifier);
LumaChromaUv.IsSpecifierAndValueValid(specifier) ||
Xyz.IsSpecifierAndValueValid(specifier);
}

/// <summary>
Expand All @@ -87,6 +88,7 @@ public static RedGreenBlue ParseSpecifierToRgb(string specifier, ColorSettings?
RedYellowBlue.IsSpecifierValid(specifier) ? RedYellowBlue.ParseSpecifierToRgb(specifier, settings) :
LumaInPhaseQuadrature.IsSpecifierValid(specifier) ? LumaInPhaseQuadrature.ParseSpecifierToRgb(specifier, settings) :
LumaChromaUv.IsSpecifierValid(specifier) ? LumaChromaUv.ParseSpecifierToRgb(specifier, settings) :
Xyz.IsSpecifierValid(specifier) ? Xyz.ParseSpecifierToRgb(specifier, settings) :

// Colors and hash
usesColorId ? ParsingTools.ParseSpecifierRgbName(specifier, settings) :
Expand Down
61 changes: 61 additions & 0 deletions Terminaux/Colors/Models/Conversion/ConversionTools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ public static RedGreenBlue ConvertToRgb<TModel>(TModel source) where TModel : Ba
rgb = ToRgb(yiq);
else if (source is LumaChromaUv yuv)
rgb = ToRgb(yuv);
else if (source is Xyz xyz)
rgb = ToRgb(xyz);
else
throw new TerminauxException("Can't convert to RGB.");
return rgb;
Expand Down Expand Up @@ -242,6 +244,9 @@ public static TResult ConvertFromRgb<TResult>(RedGreenBlue source) where TResult
else if (typeof(TResult) == typeof(LumaChromaUv))
return ToYuv(source) as TResult ??
throw new TerminauxException("Can't convert to YUV.");
else if (typeof(TResult) == typeof(Xyz))
return ToXyz(source) as TResult ??
throw new TerminauxException("Can't convert to XYZ.");
else
throw new TerminauxException("Can't convert from RGB.");
}
Expand Down Expand Up @@ -540,6 +545,31 @@ public static LumaChromaUv ToYuv(RedGreenBlue rgb)
// Return the resulting values
return new(y, u, v);
}

/// <summary>
/// Converts the RGB color model to XYZ
/// </summary>
/// <param name="rgb">Instance of RGB</param>
/// <exception cref="TerminauxException"></exception>
public static Xyz ToXyz(RedGreenBlue rgb)
{
if (rgb is null)
throw new TerminauxException("Can't convert a null RGB instance to XYZ!");

// Get the XYZ values
double r = rgb.RNormalized;
double g = rgb.GNormalized;
double b = rgb.BNormalized;
r = ((r > 0.04045d) ? Math.Pow((r + 0.055) / 1.055, 2.4) : r / 12.92d) * 100;
g = ((g > 0.04045d) ? Math.Pow((g + 0.055) / 1.055, 2.4) : g / 12.92d) * 100;
b = ((b > 0.04045d) ? Math.Pow((b + 0.055) / 1.055, 2.4) : b / 12.92d) * 100;
double x = r * 0.4124 + g * 0.3576 + b * 0.1805;
double y = r * 0.2126 + g * 0.7152 + b * 0.0722;
double z = r * 0.0193 + g * 0.1192 + b * 0.9505;

// Return the resulting values
return new(x, y, z);
}
#endregion
#region Translate to RGB from...
/// <summary>
Expand Down Expand Up @@ -825,6 +855,37 @@ public static RedGreenBlue ToRgb(LumaChromaUv yuv)
return new(r, g, b);
}

/// <summary>
/// Converts the XYZ color model to RGB
/// </summary>
/// <param name="xyz">Instance of XYZ</param>
/// <exception cref="TerminauxException"></exception>
public static RedGreenBlue ToRgb(Xyz xyz)
{
if (xyz is null)
throw new TerminauxException("Can't convert a null XYZ instance to RGB!");

// Get the normalized xyz values
double x = xyz.X / 100d;
double y = xyz.Y / 100d;
double z = xyz.Z / 100d;

// Now, convert them to RGB
double r = x * 3.2406d + y * -1.5372d + z * -0.4986d;
double g = x * -0.9689d + y * 1.8758d + z * 0.0415d;
double b = x * 0.0557d + y * -0.2040d + z * 1.0570d;
r = (r > 0.0031308) ? 1.055d * Math.Pow(r, 1 / 2.4d) - 0.055 : r * 12.92d;
g = (g > 0.0031308) ? 1.055d * Math.Pow(g, 1 / 2.4d) - 0.055 : g * 12.92d;
b = (b > 0.0031308) ? 1.055d * Math.Pow(b, 1 / 2.4d) - 0.055 : b * 12.92d;

int rWhole = (int)(r * 255);
int gWhole = (int)(g * 255);
int bWhole = (int)(b * 255);

// Install the values
return new(rWhole, gWhole, bWhole);
}

private static double GetRgbValueFromHue(double variable1, double variable2, double variableHue)
{
// Check the hue
Expand Down
Loading

0 comments on commit cf7b15e

Please sign in to comment.