Inconsistent naming of cvdMatrixes and difficult to extend
case Cvd.Protanopia:
colourTriplet1 = VisionDeficiency.ApplySimulationMatrix(colour, VisionDeficiency.Protanomaly);
break;
case Cvd.Deuteranopia:
colourTriplet1 = VisionDeficiency.ApplySimulationMatrix(colour, VisionDeficiency.Deuteranomaly);
break;
case Cvd.Tritanopia:
colourTriplet1 = VisionDeficiency.ApplySimulationMatrix(colour, VisionDeficiency.Tritanomaly);
break;
case Cvd.Achromatopsia:
colourTriplet1 = new ColourTriplet(colour.RelativeLuminance, colour.RelativeLuminance, colour.RelativeLuminance);
break;
They should be named *anpia (complete defect) instead of *anomaly (reduced)
I was going to try implement a Deutanomaly matrix but it was quite tricky as everything was internal.
I eneded up doing an extension class:
public static class UniColourExtensions
{
public static Unicolour ApplySimulationMatrix(this Unicolour colour, object cvdMatrix)
{
// Get Matrix type through reflection
var matrixAssembly = typeof(Unicolour).Assembly;
var matrixType = matrixAssembly.GetType("Wacton.Unicolour.Matrix", true);
// Convert cvdMatrix to the correct type
var matrix = Convert.ChangeType(cvdMatrix, matrixType);
// Get FromTriplet method by specifying parameter types
var fromTripletMethod = matrixType.GetMethod("FromTriplet",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Static,
null,
new[] { typeof(ColourTriplet) },
null);
// Get Multiply method by specifying parameter types
var multiplyMethod = matrixType.GetMethod("Multiply",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance,
null,
new[] { matrixType },
null);
// Get ToTriplet method
var toTripletMethod = matrixType.GetMethod("ToTriplet",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance);
if (fromTripletMethod == null || multiplyMethod == null || toTripletMethod == null)
throw new InvalidOperationException("Required Matrix methods not found");
// Create Matrix from triplet using reflection
var other = fromTripletMethod.Invoke(null, new object[] { colour.RgbLinear.Triplet });
// Multiply matrices using reflection
var result = multiplyMethod.Invoke(matrix, new[] { other });
// Convert to triplet using reflection
var colorTriplet = (ColourTriplet)toTripletMethod.Invoke(result, null);
return new Unicolour(colour.Configuration, ColourSpace.RgbLinear, colorTriplet.Tuple, colour.Alpha.A);
}
public static readonly object Deuteranomaly;
static UniColourExtensions()
{
var matrixType = typeof(Unicolour).Assembly
.GetType("Wacton.Unicolour.Matrix", true);
var matrixConstructor = matrixType.GetConstructor(
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance,
null,
new[] { typeof(double[,]) },
null);
var data = new[,] {
{ 0.80, 0.20, 0.00 },
{ 0.258, 0.742, 0.00 },
{ 0.00, 0.142, 0.858 }
};
Deuteranomaly = matrixConstructor.Invoke(new object[] { data });
}