/// <summary> /// Returns the correct matrix to convert between the Rgb and CieXyz color space. /// </summary> /// <param name="workingSpace">The Rgb working space.</param> /// <returns>The <see cref="Matrix4x4"/> based on the chromaticity and working space.</returns> public static Matrix4x4 GetRgbToCieXyzMatrix(RgbWorkingSpace workingSpace) { DebugGuard.NotNull(workingSpace, nameof(workingSpace)); RgbPrimariesChromaticityCoordinates chromaticity = workingSpace.ChromaticityCoordinates; float xr = chromaticity.R.X; float xg = chromaticity.G.X; float xb = chromaticity.B.X; float yr = chromaticity.R.Y; float yg = chromaticity.G.Y; float yb = chromaticity.B.Y; float mXr = xr / yr; const float Yr = 1; float mZr = (1 - xr - yr) / yr; float mXg = xg / yg; const float Yg = 1; float mZg = (1 - xg - yg) / yg; float mXb = xb / yb; const float Yb = 1; float mZb = (1 - xb - yb) / yb; var xyzMatrix = new Matrix4x4 { M11 = mXr, M21 = mXg, M31 = mXb, M12 = Yr, M22 = Yg, M32 = Yb, M13 = mZr, M23 = mZg, M33 = mZb, M44 = 1F }; Matrix4x4.Invert(xyzMatrix, out Matrix4x4 inverseXyzMatrix); var vector = Vector3.Transform(workingSpace.WhitePoint.ToVector3(), inverseXyzMatrix); // Use transposed Rows/Columns // TODO: Is there a built in method for this multiplication? return(new Matrix4x4 { M11 = vector.X * mXr, M21 = vector.Y * mXg, M31 = vector.Z * mXb, M12 = vector.X * Yr, M22 = vector.Y * Yg, M32 = vector.Z * Yb, M13 = vector.X * mZr, M23 = vector.Y * mZg, M33 = vector.Z * mZb, M44 = 1F }); }
/// <summary> /// Initializes a new instance of the <see cref="CieXyzToLinearRgbConverter"/> class. /// </summary> /// <param name="workingSpace">The target working space.</param> public CieXyzToLinearRgbConverter(RgbWorkingSpace workingSpace) { this.TargetWorkingSpace = workingSpace; // Gets the inverted Rgb -> Xyz matrix Matrix4x4.Invert(GetRgbToCieXyzMatrix(workingSpace), out Matrix4x4 inverted); this.conversionMatrix = inverted; }
/// <summary> /// Initializes a new instance of the <see cref="LinearRgbToCieXyzConverter"/> class. /// </summary> /// <param name="workingSpace">The target working space.</param> public LinearRgbToCieXyzConverter(RgbWorkingSpace workingSpace) { this.SourceWorkingSpace = workingSpace; this.conversionMatrix = GetRgbToCieXyzMatrix(workingSpace); }