/** * <inheritdoc /> */ public override SRGB ToSRGB(ToSmallSpaceStrategy strategy = ToSmallSpaceStrategy.ForceLowTruncate | ToSmallSpaceStrategy.ForceHighStretch) { SRGB srgbDS = DataSource as SRGB; if (srgbDS != null) { return(srgbDS); } // Linear transformation double r = X * 3.2406 + Y * -1.5372 + Z * -0.4986; double g = X * -0.9689 + Y * 1.8758 + Z * 0.0415; double b = X * 0.0557 + Y * -0.2040 + Z * 1.0570; // Gamma correction r = r > 0.0031308 ? 1.055 * Math.Pow(r, 1 / 2.4) - 0.055 : 12.92 * r; g = g > 0.0031308 ? 1.055 * Math.Pow(g, 1 / 2.4) - 0.055 : 12.92 * g; b = b > 0.0031308 ? 1.055 * Math.Pow(b, 1 / 2.4) - 0.055 : 12.92 * b; if ((strategy & ToSmallSpaceStrategy.ForceLowStretch) != 0) { double minChannelValue = Math.Min(r, Math.Min(g, b)); if (minChannelValue < 0.0) { r -= minChannelValue; g -= minChannelValue; b -= minChannelValue; } } else if ((strategy & ToSmallSpaceStrategy.ForceLowTruncate) != 0) { r = Math.Max(0.0, r); g = Math.Max(0.0, g); b = Math.Max(0.0, b); } if ((strategy & ToSmallSpaceStrategy.ForceHighStretch) != 0) { double maxChannelValue = Math.Max(r, Math.Max(g, b)); if (maxChannelValue > 1.0) { r = r / maxChannelValue; g = g / maxChannelValue; b = b / maxChannelValue; } } else if ((strategy & ToSmallSpaceStrategy.ForceHighTruncate) != 0) { r = Math.Min(1.0, r); g = Math.Min(1.0, g); b = Math.Min(1.0, b); } return(new SRGB(r, g, b, DataSource ?? this)); }
/// <summary> /// Converts from <see cref="XYZ"/> to <see cref="RGB"/> color space. /// </summary> /// <param name="x">The X channel.</param> /// <param name="y">The Y channel.</param> /// <param name="z">The Z channel.</param> /// <returns> /// The color in <see cref="RGB"/> color space. /// </returns> public static RGB ToRGB(double x, double y, double z) { // convert from CIE XYZ (D65) var red = x * D65FromXYZ[0, 0] + y * D65FromXYZ[0, 1] + z * D65FromXYZ[0, 2]; var green = x * D65FromXYZ[1, 0] + y * D65FromXYZ[1, 1] + z * D65FromXYZ[1, 2]; var blue = x * D65FromXYZ[2, 0] + y * D65FromXYZ[2, 1] + z * D65FromXYZ[2, 2]; // assume SRGB return(SRGB.ToRGB(red, green, blue)); }
/// <summary> /// Converts from <see cref="RGB"/> to <see cref="XYZ"/> color space. /// </summary> /// <param name="r">The red channel.</param> /// <param name="g">The green channel.</param> /// <param name="b">The blue channel.</param> /// <returns> /// The color in <see cref="XYZ"/> color space. /// </returns> public static XYZ FromRGB(float r, float g, float b) { // assume SRGB var srgb = SRGB.FromRGB(r, g, b); // convert to CIE XYZ return(new XYZ { X = srgb.R * D65ToXYZ[0, 0] + srgb.G * D65ToXYZ[0, 1] + srgb.B * D65ToXYZ[0, 2], Y = srgb.R * D65ToXYZ[1, 0] + srgb.G * D65ToXYZ[1, 1] + srgb.B * D65ToXYZ[1, 2], Z = srgb.R * D65ToXYZ[2, 0] + srgb.G * D65ToXYZ[2, 1] + srgb.B * D65ToXYZ[2, 2] }); }
/** * <inheritdoc /> */ public override bool Equals(Object obj) { SRGB srgbObj = obj as SRGB; if (srgbObj == this) { return(true); } if (srgbObj == null || GetHashCode() != obj.GetHashCode()) { return(false); } return(R == srgbObj.R && G == srgbObj.G && B == srgbObj.B); }