diff --git a/src/ImageProcessorCore/Filters/Processors/Binarization/BinaryThresholdProcessor.cs b/src/ImageProcessorCore/Filters/Processors/Binarization/BinaryThresholdProcessor.cs index 029f9c3b33..02b7def4a7 100644 --- a/src/ImageProcessorCore/Filters/Processors/Binarization/BinaryThresholdProcessor.cs +++ b/src/ImageProcessorCore/Filters/Processors/Binarization/BinaryThresholdProcessor.cs @@ -5,11 +5,12 @@ namespace ImageProcessorCore.Processors { + using System; using System.Threading.Tasks; /// /// An to perform binary threshold filtering against an - /// . The image will be converted to Grayscale before thresholding occurs. + /// . The image will be converted to grayscale before thresholding occurs. /// /// The pixel format. /// The packed format. long, float. @@ -18,7 +19,7 @@ namespace ImageProcessorCore.Processors where TP : struct { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The threshold to split the image. Must be between 0 and 1. /// @@ -45,12 +46,12 @@ namespace ImageProcessorCore.Processors public float Value { get; } /// - /// The color to use for pixels that are above the threshold. + /// Gets or sets the color to use for pixels that are above the threshold. /// public T UpperColor { get; set; } /// - /// The color to use for pixels that fall below the threshold. + /// Gets or sets the color to use for pixels that fall below the threshold. /// public T LowerColor { get; set; } @@ -63,38 +64,50 @@ namespace ImageProcessorCore.Processors /// protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) { - // target.SetPixels(source.Width, source.Height, source.Pixels); - - float threshold = this.Value; T upper = this.UpperColor; T lower = this.LowerColor; - int sourceY = sourceRectangle.Y; - int sourceBottom = sourceRectangle.Bottom; int startX = sourceRectangle.X; int endX = sourceRectangle.Right; + // Align start/end positions. + int minX = Math.Max(0, startX); + int maxX = Math.Min(source.Width, endX); + int minY = Math.Max(0, startY); + int maxY = Math.Min(source.Height, endY); + + // Reset offset if necessary. + if (minX > 0) + { + startX = 0; + } + + if (minY > 0) + { + startY = 0; + } + using (IPixelAccessor sourcePixels = source.Lock()) using (IPixelAccessor targetPixels = target.Lock()) { Parallel.For( - startY, - endY, - this.ParallelOptions, - y => - { - if (y >= sourceY && y < sourceBottom) + minY, + maxY, + this.ParallelOptions, + y => { - for (int x = startX; x < endX; x++) + int offsetY = y - startY; + for (int x = minX; x < maxX; x++) { - T color = sourcePixels[x, y]; + int offsetX = x - startX; + T color = sourcePixels[offsetX, offsetY]; // Any channel will do since it's Grayscale. - targetPixels[x, y] = color.ToVector4().X >= threshold ? upper : lower; + targetPixels[offsetX, offsetY] = color.ToVector4().X >= threshold ? upper : lower; } + this.OnRowProcessed(); - } - }); + }); } } }