/// <summary> /// Compute all Descriptors for the bitmap. /// </summary> /// <param name="silhouetteExtraPixels">The pixels participating in the silhouette</param> public override void ComputeDescriptor(Pixel[] silhouetteExtraPixels) { xMedianSilhouette = 0; yMedianSilhouette = 0; IColor colorSilhouette = new ColorDouble(); if (silhouetteExtraPixels != null) { foreach (Pixel silPixel in silhouetteExtraPixels) { // Silhouette only stuff xMedianSilhouette += silPixel.X; yMedianSilhouette += silPixel.Y; // compute color average colorSilhouette.ExtendedAlpha += silPixel.Color.ExtendedAlpha; colorSilhouette.ExtendedRed += silPixel.Color.ExtendedRed; colorSilhouette.ExtendedGreen += silPixel.Color.ExtendedGreen; colorSilhouette.ExtendedBlue += silPixel.Color.ExtendedBlue; } } xMedianSilhouette += xMedian * ParticipatingPixels.Length; yMedianSilhouette += yMedian * ParticipatingPixels.Length; IColor colorClone = (IColor)((ColorDouble)DescriptorDependentObjects["shapecoloraverage"]).Clone(); colorSilhouette.ExtendedAlpha += colorClone.ExtendedAlpha * ParticipatingPixels.Length; colorSilhouette.ExtendedRed += colorClone.ExtendedRed * ParticipatingPixels.Length; colorSilhouette.ExtendedGreen += colorClone.ExtendedGreen * ParticipatingPixels.Length; colorSilhouette.ExtendedBlue += colorClone.ExtendedBlue * ParticipatingPixels.Length; Normalize(((silhouetteExtraPixels == null) ? ParticipatingPixels.Length : silhouetteExtraPixels.Length + ParticipatingPixels.Length), ref xMedianSilhouette, ref yMedianSilhouette, colorSilhouette); DescriptorDependentObjects["silhouettecoloraverage"] = colorSilhouette; }
/// <summary> /// Check if two descriptor are matching, using this criterion /// </summary> /// <param name="descriptorToFind">The original descriptor</param> /// <param name="descriptorTest">The descriptor to test</param> /// <returns>true if within tolerance for this criterion, false otherwise</returns> public override bool Pass(IDescriptor descriptorToFind, IDescriptor descriptorTest) { // throw new NotImplementedException("Need to implement this ASAP"); IColor colorFind = (IColor)descriptorToFind.DescriptorDependentObjects["shapecoloraverage"]; IColor colorTest = (IColor)descriptorTest.DescriptorDependentObjects["shapecoloraverage"]; IColor colorDiff = new ColorDouble(); colorDiff.ExtendedAlpha = Math.Abs(colorFind.ExtendedAlpha - colorTest.ExtendedAlpha); colorDiff.ExtendedRed = Math.Abs(colorFind.ExtendedRed - colorTest.ExtendedRed); colorDiff.ExtendedGreen = Math.Abs(colorFind.ExtendedGreen - colorTest.ExtendedGreen); colorDiff.ExtendedBlue = Math.Abs(colorFind.ExtendedBlue - colorTest.ExtendedBlue); DistanceBetweenDescriptors = colorDiff.ExtendedAlpha + colorDiff.ExtendedRed + colorDiff.ExtendedGreen + colorDiff.ExtendedBlue; if (colorDiff.ExtendedAlpha > ((IColor)Value).ExtendedAlpha || colorDiff.ExtendedRed > ((IColor)Value).ExtendedRed || colorDiff.ExtendedGreen > ((IColor)Value).ExtendedGreen || colorDiff.ExtendedBlue > ((IColor)Value).ExtendedBlue ) { return(false); } return(true); }
/// <summary> /// Converts the given object to the type of this converter, using the specified context and culture information. /// </summary> /// <param name="context">An ITypeDescriptorContext that provides a format context.</param> /// <param name="culture">The CultureInfo to use as the current culture.</param> /// <param name="value">The Object to convert.</param> /// <returns>An Object that represents the converted value.</returns> public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { if (value is string) { try { IColor color = new ColorDouble(); if (((string)value).Trim().ToLower() != ColorDouble.Empty.ToString().ToLower()) { string ARGB = Regex.Replace((string)value, @"ARGB\s*\(\s*(.+?)\s*/\s*(.+?)\s*/\s*(.+?)\s*/\s*(.+?)\)", "$1_$2_$3_$4", RegexOptions.IgnoreCase); #if CLR_VERSION_BELOW_2 string[] channels = ARGB.Split(new char[] { '_' }); #else string[] channels = ARGB.Split(new char[] { '_' }, StringSplitOptions.RemoveEmptyEntries); #endif if (channels.Length != 4) { throw new FormatException("NormalizedColor param not formatted as expected"); } color.A = byte.Parse(channels[0]); color.R = byte.Parse(channels[1]); color.G = byte.Parse(channels[2]); color.B = byte.Parse(channels[3]); } return(color); } catch { throw new ArgumentException("Cannot convert '" + value.ToString() + "' to type 'NormalizedColor'"); } } return(base.ConvertFrom(context, culture, value)); }
private static void AssertColorsEqual(ColorDouble expected, ColorDouble actual) { Assert.IsTrue( Math.Abs(expected.R - actual.R) < 0.0001 && Math.Abs(expected.G - actual.G) < 0.0001 && Math.Abs(expected.B - actual.B) < 0.0001, string.Format("Expected color <R: {0}, G: {1}, B: {2}> but got <R: {3}, G: {4}, B: {5}>", expected.R, expected.G, expected.B, actual.R, actual.G, actual.B)); }
private IColor ProcessNot(IColor source, IColor mask) { ColorDouble retVal = new ColorDouble(); retVal.Alpha = (IgnoreAlphaChannel) ? source.Alpha : 1.0 - source.Alpha; retVal.Red = 1.0 - source.Red; retVal.Green = 1.0 - source.Green; retVal.Blue = 1.0 - source.Blue; return(retVal); }
/// <summary> /// Instanciate a ColorSpaceConversion Class /// </summary> /// <param name="color">The System.Drawing.Color to be converted</param> public ColorSpaceConversion(System.Drawing.Color color) { _argb = (ColorDouble)color; /* * if (color == Color.Empty) * { * _argb = new ColorDouble()(); * } * else * { * this.Color = color; * } */ }
/// <summary> /// Converts the given object to the type of this converter, using the specified context and culture information. /// </summary> /// <param name="context">An ITypeDescriptorContext that provides a format context.</param> /// <param name="culture">The CultureInfo to use as the current culture.</param> /// <param name="value">The Object to convert.</param> /// <returns>An Object that represents the converted value.</returns> public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { // if (value is string) if (value is System.Drawing.Color) { try { IColor color = new ColorDouble(); if (((string)value).Trim().ToLower() != ColorDouble.Empty.ToString().ToLower()) { /* * string dot = NumberFormatInfo.CurrentInfo.NumberDecimalSeparator; * if (dot == ".") { dot = "\\" + dot; } // Escape special character * string number = @"\s*(\d+" + dot + @"?\d*)\s*"; * string ARGB = Regex.Replace((string)value, ".*?" + number + "/" + number + "/" + number + "/" + number + @"\)\s*]", "$1 $2 $3 $4"); */ string ARGB = Regex.Replace((string)value, @"ARGB\s*\(\s*(.+?)\s*/\s*(.+?)\s*/\s*(.+?)\s*/\s*(.+?)\)", "$1_$2_$3_$4", RegexOptions.IgnoreCase); #if CLR_VERSION_BELOW_2 string[] channels = ARGB.Split(new char[] { '_' }); #else string[] channels = ARGB.Split(new char[] { '_' }, StringSplitOptions.None); #endif if (channels.Length != 4) { throw new FormatException("NormalizedColor param not formatted as expected"); } color.ExtendedAlpha = double.Parse(channels[0]); color.ExtendedRed = double.Parse(channels[1]); color.ExtendedGreen = double.Parse(channels[2]); color.ExtendedBlue = double.Parse(channels[3]); } return(color); } catch { throw new ArgumentException("Cannot convert '" + value.ToString() + "' to type 'NormalizedColor'"); } } return(base.ConvertFrom(context, culture, value)); }
/// <summary> /// Create a new instance of this type -- constructor defined for serializatiom /// </summary> /// <param name="info">The SerializationInfo member</param> /// <param name="context">The StreamingContext member</param> protected MomentDescriptorBase(SerializationInfo info, StreamingContext context) : base(info, context) { xMin = (int)info.GetInt32("xMin"); yMin = (int)info.GetInt32("yMin"); xMax = (int)info.GetInt32("xMax"); yMax = (int)info.GetInt32("yMax"); xMedian = (float)info.GetDouble("xMedian"); yMedian = (float)info.GetDouble("yMedian"); xMedianSilhouette = (float)info.GetDouble("xMedianSilhouette"); yMedianSilhouette = (float)info.GetDouble("yMedianSilhouette"); DescriptorSquareMatrix silhouette = (DescriptorSquareMatrix)info.GetValue("Silhouette", typeof(DescriptorSquareMatrix)); DescriptorSquareMatrix shape = (DescriptorSquareMatrix)info.GetValue("Shape", typeof(DescriptorSquareMatrix)); DescriptorSquareMatrix texture = (DescriptorSquareMatrix)info.GetValue("Texture", typeof(DescriptorSquareMatrix)); ColorDouble shapeColorAverage = (ColorDouble)info.GetValue("ShapeColorAverage", typeof(ColorDouble)); ColorDouble silhouetteColorAverage = (ColorDouble)info.GetValue("SilhouetteColorAverage", typeof(ColorDouble)); DescriptorDependentObjects.Add("silhouette", silhouette); DescriptorDependentObjects.Add("shape", shape); DescriptorDependentObjects.Add("texture", texture); DescriptorDependentObjects.Add("shapecoloraverage", shapeColorAverage); DescriptorDependentObjects.Add("silhouettecoloraverage", silhouetteColorAverage); }
/// <summary> /// Instantiate a new "colorAverage" criterion with the specified tolerance /// </summary> /// <param name="colorAverage">The amount (per channel) it can derive from the average color (normalized, usually channels between 0.0 and 1.0)</param> public ColorAverageCriterion(ColorDouble colorAverage) : base(colorAverage) { }
/// <summary> /// Instanciate a ColorSpaceConversion Class /// </summary> /// <param name="colorPrecision">The NormalizedColor to be converted</param> public ColorSpaceConversion(ColorDouble colorPrecision) { _argb = (ColorDouble)colorPrecision.Clone(); }
/// <summary> /// Instanciate a ColorSpaceConversion Class /// </summary> public ColorSpaceConversion() { _argb = new ColorDouble(); }
/// <summary> /// Filter Implementation /// </summary> protected override IImageAdapter ProcessFilter(IImageAdapter source) { if (source == null) { throw new ArgumentNullException("source", "The IImageAdapter must be set to a valid instance (null passed in)"); } if (Length == 0 && _kernel.Length == 0) { // Length is zero, no gaussian to be applied; return same imageAdapter as the one passed in return((IImageAdapter)source.Clone()); } int width = source.Width; int height = source.Height; ImageAdapter retVal = new ImageAdapter(width, height); // If necessary, create the kernel to be used by the Gaussian filter if (_kernel.Length == 0) { GenerateKernel(); } // ( the kernel is separable -- two pass algorithm : horizontal then vertical pass ) ImageAdapter itemp = new ImageAdapter(width, height); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { IColor lcol = new ColorDouble(); for (int i = 0; i < _kernel.Length; i++) { int minus = x - i; if (minus < 0) { // out of bound, mirror it int remainder = 0; int evenNumber = Math.DivRem(1 + minus, width, out remainder); minus = (((evenNumber >> 1) << 1) == evenNumber) ? -remainder : width - 1 + remainder; } IColor lbc = source[minus, y]; lcol.ExtendedAlpha += _kernel[i] * lbc.ExtendedAlpha; lcol.ExtendedRed += _kernel[i] * lbc.ExtendedRed; lcol.ExtendedGreen += _kernel[i] * lbc.ExtendedGreen; lcol.ExtendedBlue += _kernel[i] * lbc.ExtendedBlue; int plus = x + i; if (plus >= width) { // out of bound, mirror it int remainder = 0; int evenNumber = Math.DivRem(plus, width, out remainder); plus = (((evenNumber >> 1) << 1) == evenNumber) ? remainder : width - 1 - remainder; } IColor lfc = source[plus, y]; lcol.ExtendedAlpha += _kernel[i] * lfc.ExtendedAlpha; lcol.ExtendedRed += _kernel[i] * lfc.ExtendedRed; lcol.ExtendedGreen += _kernel[i] * lfc.ExtendedGreen; lcol.ExtendedBlue += _kernel[i] * lfc.ExtendedBlue; } itemp[x, y] = lcol; } } for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { IColor lcol = new ColorDouble(); for (int i = 0; i < _kernel.Length; i++) { int minus = y - i; if (minus < 0) { // out of bound, mirror it int remainder = 0; int evenNumber = Math.DivRem(1 + minus, height, out remainder); minus = (((evenNumber >> 1) << 1) == evenNumber) ? -remainder : height - 1 + remainder; } IColor lbc = itemp[x, minus]; lcol.ExtendedAlpha += _kernel[i] * lbc.ExtendedAlpha; lcol.ExtendedRed += _kernel[i] * lbc.ExtendedRed; lcol.ExtendedGreen += _kernel[i] * lbc.ExtendedGreen; lcol.ExtendedBlue += _kernel[i] * lbc.ExtendedBlue; int plus = y + i; if (plus >= height) { // out of bound, mirror it int remainder = 0; int evenNumber = Math.DivRem(plus, height, out remainder); plus = (((evenNumber >> 1) << 1) == evenNumber) ? remainder : height - 1 - remainder; } IColor lfc = itemp[x, plus]; lcol.ExtendedAlpha += _kernel[i] * lfc.ExtendedAlpha; lcol.ExtendedRed += _kernel[i] * lfc.ExtendedRed; lcol.ExtendedGreen += _kernel[i] * lfc.ExtendedGreen; lcol.ExtendedBlue += _kernel[i] * lfc.ExtendedBlue; } retVal[x, y] = lcol; } } // Convert ColorDouble to the IColor type of the source imageAdapter for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if (retVal[x, y].GetType() != source[x, y].GetType()) { IColor temp = (IColor)source[x, y].Clone(); temp.ExtendedAlpha = retVal[x, y].ExtendedAlpha; temp.ExtendedRed = retVal[x, y].ExtendedRed; temp.ExtendedGreen = retVal[x, y].ExtendedGreen; temp.ExtendedBlue = retVal[x, y].ExtendedBlue; retVal[x, y] = temp; } } } return(retVal); }
/// <summary> /// Perform the PixelizeFilter /// </summary> /// <param name="source">The image to be processed</param> /// <returns>the processed image</returns> protected override IImageAdapter ProcessFilter(IImageAdapter source) { int squareSize = SquareSize; ImageAdapter retVal = new ImageAdapter(source.Width, source.Height); int extendedSize = ExtendedSize; if (extendedSize == 1) { return((IImageAdapter)source.Clone()); } ArrayList tempAlpha = null; ArrayList tempRed = null; ArrayList tempGreen = null; ArrayList tempBlue = null; int mean = 0; int count = 0; IColor tempColor = null; IColor color = null; if (UseMean) { int extended = extendedSize * extendedSize; tempAlpha = new ArrayList(extended); tempRed = new ArrayList(extended); tempGreen = new ArrayList(extended); tempBlue = new ArrayList(extended); } for (int y = 0; y < source.Height; y += squareSize) { for (int x = 0; x < source.Width; x += squareSize) { count = 0; color = new ColorDouble(0.0, 0.0, 0.0, 0.0); for (int height = -extendedSize / 2; height < extendedSize / 2f; height++) { for (int width = -extendedSize / 2; width < extendedSize / 2f; width++) { if (x + width >= 0 && y + height >= 0 && x + width < source.Width && y + height < source.Height) { tempColor = source[x + width, y + height]; if (UseMean) { tempAlpha.Add(tempColor.ExtendedAlpha); tempRed.Add(tempColor.ExtendedRed); tempGreen.Add(tempColor.ExtendedGreen); tempBlue.Add(tempColor.ExtendedBlue); } else { count++; color.ExtendedAlpha += tempColor.ExtendedAlpha; color.ExtendedRed += tempColor.ExtendedRed; color.ExtendedGreen += tempColor.ExtendedGreen; color.ExtendedBlue += tempColor.ExtendedBlue; } } } } if (UseMean) { tempAlpha.Sort(); tempRed.Sort(); tempGreen.Sort(); tempBlue.Sort(); mean = tempAlpha.Count / 2; color.ExtendedAlpha = (double)tempAlpha[mean]; color.ExtendedRed = (double)tempRed[mean]; color.ExtendedGreen = (double)tempGreen[mean]; color.ExtendedBlue = (double)tempBlue[mean]; tempAlpha.Clear(); tempRed.Clear(); tempGreen.Clear(); tempBlue.Clear(); } else { color.ExtendedAlpha /= count; color.ExtendedRed /= count; color.ExtendedGreen /= count; color.ExtendedBlue /= count; } for (int y2 = 0; y2 < squareSize; y2++) { for (int x2 = 0; x2 < squareSize; x2++) { if (x + x2 < source.Width && y + y2 < source.Height) { retVal[x + x2, y + y2] = color; } } } } } return(retVal); }
/// <summary> /// Filter Implementation /// </summary> protected override IImageAdapter ProcessFilter(IImageAdapter source) { ImageAdapter retVal = new ImageAdapter(source.Width, source.Height); // Convert HSL to RGB HSLColor hsl = new HSLColor(); hsl.H = ((Hue + 360.0) % 360) / 360.0; // Normalize -180/180 to 0/1 hsl.S = 1.0; hsl.L = 0.5; ColorSpaceConversion colorConvert = new ColorSpaceConversion(); colorConvert.HSL = hsl; IColor tintColor = colorConvert.ColorDouble; // multiply every color channel by amount double amount = Amount; tintColor.ExtendedRed *= Amount; tintColor.ExtendedGreen *= Amount; tintColor.ExtendedBlue *= Amount; if (Amount < 0.0) { amount *= -1; tintColor.ExtendedRed = 1.0 + tintColor.ExtendedRed; tintColor.ExtendedGreen = 1.0 + tintColor.ExtendedGreen; tintColor.ExtendedBlue = 1.0 + tintColor.ExtendedBlue; } // Tint all pixels IColor newColor = null; IColor tempColor = null; double luminance = 0.0; int height = source.Height; int width = source.Width; double temp = 0.0; double maxChannel = 0.0; int x = 0; int y = 0; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { tempColor = new ColorDouble((IColor)source[x, y]); if (tempColor.IsEmpty) { retVal[x, y] = tempColor; continue; } luminance = tempColor.ExtendedRed * MIL_LUMINANCE_RED + tempColor.ExtendedGreen * MIL_LUMINANCE_GREEN + tempColor.ExtendedBlue * MIL_LUMINANCE_BLUE; maxChannel = Math.Max(Math.Max(source[x, y].ExtendedRed, source[x, y].ExtendedGreen), source[x, y].ExtendedBlue); temp = source[x, y].ExtendedRed * (1.0 - amount) + tintColor.ExtendedRed * maxChannel; tempColor.ExtendedRed = temp; temp = source[x, y].ExtendedGreen * (1.0 - amount) + tintColor.ExtendedGreen * maxChannel; tempColor.ExtendedGreen = temp; temp = source[x, y].ExtendedBlue * (1.0 - amount) + tintColor.ExtendedBlue * maxChannel; tempColor.ExtendedBlue = temp; // restore the original luminance double deltaLum = luminance - (tempColor.ExtendedRed * MIL_LUMINANCE_RED + tempColor.ExtendedGreen * MIL_LUMINANCE_GREEN + tempColor.ExtendedBlue * MIL_LUMINANCE_BLUE); newColor = (IColor)source[x, y].Clone(); newColor.ExtendedRed = tempColor.ExtendedRed + deltaLum; newColor.ExtendedGreen = tempColor.ExtendedGreen + deltaLum; newColor.ExtendedBlue = tempColor.ExtendedBlue + deltaLum; retVal[x, y] = newColor; } } return(retVal); }
public static IImageAdapter ScaleDown(double horizontalScaling, double verticalScaling, IImageAdapter imageSource) { if (horizontalScaling <= 0.0 || verticalScaling <= 0.0) { throw new ArgumentOutOfRangeException("horizontalScaling and verticalScaling must be strictly positive"); } IImageAdapter retVal = (IImageAdapter)imageSource.Clone(); double deltaX = Math.Max(1.0, 1 / horizontalScaling); double deltaY = Math.Max(1.0, 1 / verticalScaling); if (deltaX != 1.0) { // Pass 1 : average on the x axis for (int y = 0; y < retVal.Height; y++) { for (int x = 0; x < retVal.Width; x += (int)deltaX) { int weight = 0; ColorDouble color = new ColorDouble(); for (int t = 0; t < (int)deltaX && x + t < retVal.Width; t++) { weight++; color.ExtendedAlpha += imageSource[x + t, y].ExtendedAlpha; color.ExtendedRed += imageSource[x + t, y].ExtendedRed; color.ExtendedGreen += imageSource[x + t, y].ExtendedGreen; color.ExtendedBlue += imageSource[x + t, y].ExtendedBlue; } color.ExtendedAlpha /= weight; color.ExtendedRed /= weight; color.ExtendedGreen /= weight; color.ExtendedBlue /= weight; for (int t = 0; t < (int)deltaX && x + t < retVal.Width; t++) { retVal[x + t, y].ExtendedAlpha = color.ExtendedAlpha; retVal[x + t, y].ExtendedRed = color.ExtendedRed; retVal[x + t, y].ExtendedGreen = color.ExtendedGreen; retVal[x + t, y].ExtendedBlue = color.ExtendedBlue; } } } } if (deltaY != 1.0) { // Pass 2 : average on the y axis for (int y = 0; y < (int)deltaY; y += (int)deltaY) { for (int x = 0; x < (int)deltaX; x += (int)deltaX) { int weight = 0; ColorDouble color = new ColorDouble(); for (int t = 0; t < (int)deltaY && y + t < retVal.Height; t++) { weight++; color.ExtendedAlpha += imageSource[x, y + t].ExtendedAlpha; color.ExtendedRed += imageSource[x, y + t].ExtendedRed; color.ExtendedGreen += imageSource[x, y + t].ExtendedGreen; color.ExtendedBlue += imageSource[x, y + t].ExtendedBlue; } color.ExtendedAlpha /= weight; color.ExtendedRed /= weight; color.ExtendedGreen /= weight; color.ExtendedBlue /= weight; for (int t = 0; t < (int)deltaY && y + t < retVal.Height; t++) { retVal[x, y + t].ExtendedAlpha = color.ExtendedAlpha; retVal[x, y + t].ExtendedRed = color.ExtendedRed; retVal[x, y + t].ExtendedGreen = color.ExtendedGreen; retVal[x, y + t].ExtendedBlue = color.ExtendedBlue; } } } } return(retVal); }
/// <summary> /// Filter implementation /// </summary> protected override IImageAdapter ProcessFilter(IImageAdapter source) { if (ColorAboveThresold == ColorBelowThresold) { throw new ArgumentException("ColorAboveThreshold and ColorBelowThreshold cannot be the same"); } IImageAdapter retVal = (IImageAdapter)source.Clone(); double[,] kernel = Kernel; int kHeight = kernel.GetUpperBound(0) / 2; int kWidth = kernel.GetUpperBound(1) / 2; IColor colorSum = null; IColor tempColor = null; int count = 0; for (int y = 0; y < source.Height; y++) { for (int x = 0; x < source.Width; x++) { colorSum = new ColorDouble(); count = 0; for (int height = -kHeight; height <= kHeight; height++) { for (int width = -kWidth; width <= kWidth; width++) { // If out of bound mirror the image // int xPos = x + width; int yPos = y + height; if (xPos < 0) { xPos = Math.Abs(xPos); } if (xPos >= source.Width) { xPos = source.Width - xPos; } if (yPos < 0) { yPos = Math.Abs(yPos); } if (yPos >= source.Height) { yPos = source.Height - yPos; } tempColor = source[xPos, yPos]; colorSum.ExtendedAlpha += tempColor.ExtendedAlpha * kernel[width + kWidth, height + kHeight]; colorSum.ExtendedRed += tempColor.ExtendedRed * kernel[width + kWidth, height + kHeight]; colorSum.ExtendedGreen += tempColor.ExtendedGreen * kernel[width + kWidth, height + kHeight]; colorSum.ExtendedBlue += tempColor.ExtendedBlue * kernel[width + kWidth, height + kHeight]; count++; } } if ((Math.Abs(colorSum.ExtendedAlpha) + Math.Abs(colorSum.ExtendedRed) + Math.Abs(colorSum.ExtendedGreen) + Math.Abs(colorSum.ExtendedBlue)) / (count * 4) > Threshold + EPSILON) { retVal[x, y] = (IColor)ColorAboveThresold.Clone(); } else { retVal[x, y] = (IColor)ColorBelowThresold.Clone(); } } } return(retVal); }
private ImageAdapter GenerateGlowImage(IImageAdapter source) { int xSize = (int)((Radius + 1) / 2); int ySize = (int)((Radius + 1) / 2); int width = source.Width; int height = source.Height; ImageAdapter retVal = (ImageAdapter)source.Clone(); // for each transparent pixel, find the closest color for (int y = 0; y < retVal.Height; y++) { for (int x = 0; x < retVal.Width; x++) { if (retVal[x, y].A > GLOW_ALPHA_THRESHOLD) { retVal[x, y].IsEmpty = true; continue; } IColor color = new ColorDouble(); retVal[x, y] = color; for (int xDelta = -xSize; xDelta < xSize; xDelta++) { for (int yDelta = -ySize; yDelta < ySize; yDelta++) { if (x + xDelta < 0 || y + yDelta < 0 || x + xDelta >= width || y + yDelta >= height) { continue; } IColor temp = source[x + xDelta, y + yDelta]; if (temp.Alpha > GLOW_ALPHA_THRESHOLD / temp.NormalizedValue) { double distance = Math.Sqrt(xDelta * xDelta + yDelta * yDelta); if (distance > Radius || (color.ExtendedAlpha != 0 && distance >= color.ExtendedAlpha)) { continue; } color.ExtendedAlpha = distance; } } } } } // Parse the Array and map the distance to the appropriate color for (int y = 0; y < retVal.Height; y++) { for (int x = 0; x < retVal.Width; x++) { IColor color = retVal[x, y]; if (color.Alpha != 0.0) { retVal[x, y] = GetMappedColor(color); } else { if (Composite) { retVal[x, y] = (IColor)source[x, y].Clone(); } } } } return(retVal); }