/// <summary> /// Merge two color using the Alpha channel value as multiplier /// </summary> /// <param name="colorPrecision1">The first color to merge</param> /// <param name="colorPrecision2">The second color to merge</param> /// <returns>The merge color (averaging based on the alpha channel)</returns> // @ review : assume not premultiply ? // @ review : Use Extended or regular value ? // @ review : if both color are opaque should be just add them (instead of averaging them) ? // ...Might help some customer but would be inconstient (not done for now) public static ColorDouble operator +(ColorDouble colorPrecision1, ColorDouble colorPrecision2) { ColorDouble retVal = new ColorDouble(); if (colorPrecision1.IsEmpty == false && colorPrecision2.IsEmpty == false) { double dividend = ColorDouble._maxChannelValue * 2 - ColorDouble._minChannelValue; retVal.ExtendedAlpha = Math.Max(colorPrecision1.ExtendedAlpha, colorPrecision2.ExtendedAlpha); retVal.ExtendedRed = (colorPrecision1.ExtendedRed * colorPrecision1.ExtendedAlpha + colorPrecision2.ExtendedRed * colorPrecision2.ExtendedAlpha) / dividend; retVal.ExtendedGreen = (colorPrecision1.ExtendedGreen * colorPrecision1.ExtendedAlpha + colorPrecision2.ExtendedGreen * colorPrecision2.ExtendedAlpha) / dividend; retVal.ExtendedBlue = (colorPrecision1.ExtendedBlue * colorPrecision1.ExtendedAlpha + colorPrecision2.ExtendedBlue * colorPrecision2.ExtendedAlpha) / dividend; retVal._isDefined = true; } else { if (colorPrecision1.IsEmpty) { retVal = (ColorDouble)colorPrecision2.Clone(); } else { retVal = (ColorDouble)colorPrecision1.Clone(); } } return(retVal); }
/// <summary> /// Negate a color without affecting the alpha channel. /// </summary> /// <param name="colorPrecision">The color to negate</param> /// <returns>The negated color</returns> // @ review : IGNORE alpha ? (we are right now) // @review : Should we Use ExtendedAlpha here ? Does not make much sense for Negating a color public static ColorDouble operator !(ColorDouble colorPrecision) { ColorDouble retVal = new ColorDouble(); if (colorPrecision.IsEmpty) { return(retVal); } retVal.ExtendedAlpha = colorPrecision.ExtendedAlpha; retVal.ExtendedRed = ColorDouble._maxChannelValue - colorPrecision.ExtendedRed; retVal.ExtendedGreen = ColorDouble._maxChannelValue - colorPrecision.ExtendedGreen; retVal.ExtendedBlue = ColorDouble._maxChannelValue - colorPrecision.ExtendedBlue; retVal._isDefined = true; return(retVal); }
/// <summary> /// Un-Merge two color using the Alpha channel value as multiplier /// </summary> /// <param name="colorPrecision1">The resulting color</param> /// <param name="colorPrecision2">The color to remove from the resulting image</param> /// <returns>The merging color (color that would lead to color one perform "thisColor + color2")</returns> // @ review : assume not premultiply ? // @ review : Use Extended or regular value ? // @ review : if both color are opaque should be just subtract them (instead of un-averaging them) ? // ...Might help some customer but would be inconstient (not done for now) public static ColorDouble operator -(ColorDouble colorPrecision1, ColorDouble colorPrecision2) { ColorDouble retVal = new ColorDouble(); if (colorPrecision1.IsEmpty == false || colorPrecision2.IsEmpty == false) { double dividend = ColorDouble._maxChannelValue; retVal.ExtendedAlpha = Math.Max(colorPrecision1.ExtendedAlpha, colorPrecision2.ExtendedAlpha); retVal.ExtendedRed = (colorPrecision1.ExtendedRed * colorPrecision1.ExtendedAlpha * 2 - colorPrecision2.ExtendedRed * colorPrecision2.ExtendedAlpha) / dividend; retVal.ExtendedGreen = (colorPrecision1.ExtendedGreen * colorPrecision1.ExtendedAlpha * 2 - colorPrecision2.ExtendedGreen * colorPrecision2.ExtendedAlpha) / dividend; retVal.ExtendedBlue = (colorPrecision1.ExtendedBlue * colorPrecision1.ExtendedAlpha * 2 - colorPrecision2.ExtendedBlue * colorPrecision2.ExtendedAlpha) / dividend; retVal._isDefined = true; } return(retVal); }