From 4f5fd68f558f2d3d08765fdb496c3009056f1590 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Sun, 11 Dec 2016 23:49:17 +1100 Subject: [PATCH] Simplify filter API further No need for startY, endY parameters. --- .../Binarization/BinaryThresholdProcessor.cs | 7 +- .../ColorMatrix/ColorMatrixFilter.cs | 4 +- .../Convolution/BoxBlurProcessor.cs | 2 +- .../Convolution/Convolution2DProcessor.cs | 95 +++++++++---------- .../Convolution/Convolution2PassProcessor.cs | 15 ++- .../Convolution/ConvolutionProcessor.cs | 69 +++++++------- .../EdgeDetection/EdgeDetector2DProcessor.cs | 4 +- .../EdgeDetectorCompassProcessor.cs | 6 +- .../EdgeDetection/EdgeDetectorProcessor.cs | 4 +- .../Convolution/GaussianBlurProcessor.cs | 2 +- .../Convolution/GaussianSharpenProcessor.cs | 2 +- .../Processors/Effects/AlphaProcessor.cs | 5 +- .../Effects/BackgroundColorProcessor.cs | 4 +- .../Processors/Effects/BrightnessProcessor.cs | 5 +- .../Processors/Effects/ContrastProcessor.cs | 5 +- .../Processors/Effects/InvertProcessor.cs | 4 +- .../Effects/OilPaintingProcessor.cs | 4 +- .../Processors/Effects/PixelateProcessor.cs | 4 +- .../Processors/ImageFilteringProcessor.cs | 20 ++-- .../Processors/Overlays/BlendProcessor.cs | 6 +- .../Processors/Overlays/GlowProcessor.cs | 4 +- .../Processors/Overlays/VignetteProcessor.cs | 4 +- .../Transforms/CompandingResizeProcessor.cs | 8 +- .../Processors/Transforms/CropProcessor.cs | 6 +- .../Transforms/EntropyCropProcessor.cs | 2 +- .../Processors/Transforms/FlipProcessor.cs | 2 +- .../Transforms/ResamplingWeightedProcessor.cs | 2 +- .../Processors/Transforms/ResizeProcessor.cs | 8 +- .../Processors/Transforms/RotateProcessor.cs | 4 +- .../Processors/Transforms/SkewProcessor.cs | 4 +- .../Processors/Filters/OilPaintTest.cs | 17 ++-- 31 files changed, 174 insertions(+), 154 deletions(-) diff --git a/src/ImageSharp/Filters/Processors/Binarization/BinaryThresholdProcessor.cs b/src/ImageSharp/Filters/Processors/Binarization/BinaryThresholdProcessor.cs index 407dd8d053..64aa72401e 100644 --- a/src/ImageSharp/Filters/Processors/Binarization/BinaryThresholdProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Binarization/BinaryThresholdProcessor.cs @@ -56,17 +56,20 @@ namespace ImageSharp.Processors public TColor LowerColor { get; set; } /// - protected override void OnApply(ImageBase source, Rectangle sourceRectangle) + protected override void BeforeApply(ImageBase source, Rectangle sourceRectangle) { new GrayscaleBt709Processor().Apply(source, sourceRectangle); } /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { float threshold = this.Value; TColor upper = this.UpperColor; TColor lower = this.LowerColor; + + int startY = sourceRectangle.Y; + int endY = sourceRectangle.Bottom; int startX = sourceRectangle.X; int endX = sourceRectangle.Right; diff --git a/src/ImageSharp/Filters/Processors/ColorMatrix/ColorMatrixFilter.cs b/src/ImageSharp/Filters/Processors/ColorMatrix/ColorMatrixFilter.cs index 149ef6bc11..4c4868a01f 100644 --- a/src/ImageSharp/Filters/Processors/ColorMatrix/ColorMatrixFilter.cs +++ b/src/ImageSharp/Filters/Processors/ColorMatrix/ColorMatrixFilter.cs @@ -25,8 +25,10 @@ namespace ImageSharp.Processors public override bool Compand { get; set; } = true; /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { + int startY = sourceRectangle.Y; + int endY = sourceRectangle.Bottom; int startX = sourceRectangle.X; int endX = sourceRectangle.Right; diff --git a/src/ImageSharp/Filters/Processors/Convolution/BoxBlurProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/BoxBlurProcessor.cs index efe5fcf7ef..bc20bde3e9 100644 --- a/src/ImageSharp/Filters/Processors/Convolution/BoxBlurProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Convolution/BoxBlurProcessor.cs @@ -43,7 +43,7 @@ namespace ImageSharp.Processors public float[][] KernelY { get; } /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { new Convolution2PassProcessor(this.KernelX, this.KernelY).Apply(source, sourceRectangle); } diff --git a/src/ImageSharp/Filters/Processors/Convolution/Convolution2DProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/Convolution2DProcessor.cs index afebcd8ed7..86e3a26245 100644 --- a/src/ImageSharp/Filters/Processors/Convolution/Convolution2DProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Convolution/Convolution2DProcessor.cs @@ -40,7 +40,7 @@ namespace ImageSharp.Processors public float[][] KernelY { get; } /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { int kernelYHeight = this.KernelY.Length; int kernelYWidth = this.KernelY[0].Length; @@ -49,11 +49,11 @@ namespace ImageSharp.Processors int radiusY = kernelYHeight >> 1; int radiusX = kernelXWidth >> 1; - int sourceY = sourceRectangle.Y; - int sourceBottom = sourceRectangle.Bottom; + int startY = sourceRectangle.Y; + int endY = sourceRectangle.Bottom; int startX = sourceRectangle.X; int endX = sourceRectangle.Right; - int maxY = sourceBottom - 1; + int maxY = endY - 1; int maxX = endX - 1; TColor[] target = new TColor[source.Width * source.Height]; @@ -66,61 +66,58 @@ namespace ImageSharp.Processors this.ParallelOptions, y => { - if (y >= sourceY && y < sourceBottom) + for (int x = startX; x < endX; x++) { - for (int x = startX; x < endX; x++) + float rX = 0; + float gX = 0; + float bX = 0; + float rY = 0; + float gY = 0; + float bY = 0; + + // Apply each matrix multiplier to the color components for each pixel. + for (int fy = 0; fy < kernelYHeight; fy++) { - float rX = 0; - float gX = 0; - float bX = 0; - float rY = 0; - float gY = 0; - float bY = 0; - - // Apply each matrix multiplier to the color components for each pixel. - for (int fy = 0; fy < kernelYHeight; fy++) + int fyr = fy - radiusY; + int offsetY = y + fyr; + + offsetY = offsetY.Clamp(0, maxY); + + for (int fx = 0; fx < kernelXWidth; fx++) { - int fyr = fy - radiusY; - int offsetY = y + fyr; + int fxr = fx - radiusX; + int offsetX = x + fxr; + + offsetX = offsetX.Clamp(0, maxX); + + Vector4 currentColor = sourcePixels[offsetX, offsetY].ToVector4(); + float r = currentColor.X; + float g = currentColor.Y; + float b = currentColor.Z; - offsetY = offsetY.Clamp(0, maxY); + if (fy < kernelXHeight) + { + rX += this.KernelX[fy][fx] * r; + gX += this.KernelX[fy][fx] * g; + bX += this.KernelX[fy][fx] * b; + } - for (int fx = 0; fx < kernelXWidth; fx++) + if (fx < kernelYWidth) { - int fxr = fx - radiusX; - int offsetX = x + fxr; - - offsetX = offsetX.Clamp(0, maxX); - - Vector4 currentColor = sourcePixels[offsetX, offsetY].ToVector4(); - float r = currentColor.X; - float g = currentColor.Y; - float b = currentColor.Z; - - if (fy < kernelXHeight) - { - rX += this.KernelX[fy][fx] * r; - gX += this.KernelX[fy][fx] * g; - bX += this.KernelX[fy][fx] * b; - } - - if (fx < kernelYWidth) - { - rY += this.KernelY[fy][fx] * r; - gY += this.KernelY[fy][fx] * g; - bY += this.KernelY[fy][fx] * b; - } + rY += this.KernelY[fy][fx] * r; + gY += this.KernelY[fy][fx] * g; + bY += this.KernelY[fy][fx] * b; } } + } - float red = (float)Math.Sqrt((rX * rX) + (rY * rY)); - float green = (float)Math.Sqrt((gX * gX) + (gY * gY)); - float blue = (float)Math.Sqrt((bX * bX) + (bY * bY)); + float red = (float)Math.Sqrt((rX * rX) + (rY * rY)); + float green = (float)Math.Sqrt((gX * gX) + (gY * gY)); + float blue = (float)Math.Sqrt((bX * bX) + (bY * bY)); - TColor packed = default(TColor); - packed.PackFromVector4(new Vector4(red, green, blue, sourcePixels[x, y].ToVector4().W)); - targetPixels[x, y] = packed; - } + TColor packed = default(TColor); + packed.PackFromVector4(new Vector4(red, green, blue, sourcePixels[x, y].ToVector4().W)); + targetPixels[x, y] = packed; } }); } diff --git a/src/ImageSharp/Filters/Processors/Convolution/Convolution2PassProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/Convolution2PassProcessor.cs index 42e48cf424..38bfb73003 100644 --- a/src/ImageSharp/Filters/Processors/Convolution/Convolution2PassProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Convolution/Convolution2PassProcessor.cs @@ -39,7 +39,7 @@ namespace ImageSharp.Processors public float[][] KernelY { get; } /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { float[][] kernelX = this.KernelX; float[][] kernelY = this.KernelY; @@ -49,8 +49,8 @@ namespace ImageSharp.Processors TColor[] target = new TColor[width * height]; TColor[] firstPass = new TColor[width * height]; - this.ApplyConvolution(width, height, firstPass, source.Pixels, sourceRectangle, startY, endY, kernelX); - this.ApplyConvolution(width, height, target, firstPass, sourceRectangle, startY, endY, kernelY); + this.ApplyConvolution(width, height, firstPass, source.Pixels, sourceRectangle, kernelX); + this.ApplyConvolution(width, height, target, firstPass, sourceRectangle, kernelY); source.SetPixels(width, height, target); } @@ -66,20 +66,19 @@ namespace ImageSharp.Processors /// /// The structure that specifies the portion of the image object to draw. /// - /// The index of the row within the source image to start processing. - /// The index of the row within the source image to end processing. /// The kernel operator. - private void ApplyConvolution(int width, int height, TColor[] target, TColor[] source, Rectangle sourceRectangle, int startY, int endY, float[][] kernel) + private void ApplyConvolution(int width, int height, TColor[] target, TColor[] source, Rectangle sourceRectangle, float[][] kernel) { int kernelHeight = kernel.Length; int kernelWidth = kernel[0].Length; int radiusY = kernelHeight >> 1; int radiusX = kernelWidth >> 1; - int sourceBottom = sourceRectangle.Bottom; + int startY = sourceRectangle.Y; + int endY = sourceRectangle.Bottom; int startX = sourceRectangle.X; int endX = sourceRectangle.Right; - int maxY = sourceBottom - 1; + int maxY = endY - 1; int maxX = endX - 1; using (PixelAccessor sourcePixels = source.Lock(width, height)) diff --git a/src/ImageSharp/Filters/Processors/Convolution/ConvolutionProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/ConvolutionProcessor.cs index f7664904ec..435718de3c 100644 --- a/src/ImageSharp/Filters/Processors/Convolution/ConvolutionProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Convolution/ConvolutionProcessor.cs @@ -32,17 +32,17 @@ namespace ImageSharp.Processors public virtual float[][] KernelXY { get; } /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { float[][] kernelX = this.KernelXY; int kernelLength = kernelX.GetLength(0); int radius = kernelLength >> 1; - int sourceY = sourceRectangle.Y; - int sourceBottom = sourceRectangle.Bottom; + int startY = sourceRectangle.Y; + int endY = sourceRectangle.Bottom; int startX = sourceRectangle.X; int endX = sourceRectangle.Right; - int maxY = sourceBottom - 1; + int maxY = endY - 1; int maxX = endX - 1; TColor[] target = new TColor[source.Width * source.Height]; @@ -55,48 +55,45 @@ namespace ImageSharp.Processors this.ParallelOptions, y => { - if (y >= sourceY && y < sourceBottom) + for (int x = startX; x < endX; x++) { - for (int x = startX; x < endX; x++) - { - float rX = 0; - float gX = 0; - float bX = 0; + float rX = 0; + float gX = 0; + float bX = 0; - // Apply each matrix multiplier to the color components for each pixel. - for (int fy = 0; fy < kernelLength; fy++) - { - int fyr = fy - radius; - int offsetY = y + fyr; + // Apply each matrix multiplier to the color components for each pixel. + for (int fy = 0; fy < kernelLength; fy++) + { + int fyr = fy - radius; + int offsetY = y + fyr; - offsetY = offsetY.Clamp(0, maxY); + offsetY = offsetY.Clamp(0, maxY); - for (int fx = 0; fx < kernelLength; fx++) - { - int fxr = fx - radius; - int offsetX = x + fxr; + for (int fx = 0; fx < kernelLength; fx++) + { + int fxr = fx - radius; + int offsetX = x + fxr; - offsetX = offsetX.Clamp(0, maxX); + offsetX = offsetX.Clamp(0, maxX); - Vector4 currentColor = sourcePixels[offsetX, offsetY].ToVector4(); - float r = currentColor.X; - float g = currentColor.Y; - float b = currentColor.Z; + Vector4 currentColor = sourcePixels[offsetX, offsetY].ToVector4(); + float r = currentColor.X; + float g = currentColor.Y; + float b = currentColor.Z; - rX += kernelX[fy][fx] * r; - gX += kernelX[fy][fx] * g; - bX += kernelX[fy][fx] * b; - } + rX += kernelX[fy][fx] * r; + gX += kernelX[fy][fx] * g; + bX += kernelX[fy][fx] * b; } + } - float red = rX; - float green = gX; - float blue = bX; + float red = rX; + float green = gX; + float blue = bX; - TColor packed = default(TColor); - packed.PackFromVector4(new Vector4(red, green, blue, sourcePixels[x, y].ToVector4().W)); - targetPixels[x, y] = packed; - } + TColor packed = default(TColor); + packed.PackFromVector4(new Vector4(red, green, blue, sourcePixels[x, y].ToVector4().W)); + targetPixels[x, y] = packed; } }); } diff --git a/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetector2DProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetector2DProcessor.cs index 0acb69980c..753883f3cd 100644 --- a/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetector2DProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetector2DProcessor.cs @@ -28,13 +28,13 @@ namespace ImageSharp.Processors public bool Grayscale { get; set; } /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { new Convolution2DProcessor(this.KernelX, this.KernelY).Apply(source, sourceRectangle); } /// - protected override void OnApply(ImageBase source, Rectangle sourceRectangle) + protected override void BeforeApply(ImageBase source, Rectangle sourceRectangle) { if (this.Grayscale) { diff --git a/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetectorCompassProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetectorCompassProcessor.cs index 59cf632426..bc78a2e5cc 100644 --- a/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetectorCompassProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetectorCompassProcessor.cs @@ -62,10 +62,12 @@ namespace ImageSharp.Processors public bool Grayscale { get; set; } /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { float[][][] kernels = { this.North, this.NorthWest, this.West, this.SouthWest, this.South, this.SouthEast, this.East, this.NorthEast }; + int startY = sourceRectangle.Y; + int endY = sourceRectangle.Bottom; int startX = sourceRectangle.X; int endX = sourceRectangle.Right; @@ -136,7 +138,7 @@ namespace ImageSharp.Processors } /// - protected override void OnApply(ImageBase source, Rectangle sourceRectangle) + protected override void BeforeApply(ImageBase source, Rectangle sourceRectangle) { if (this.Grayscale) { diff --git a/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetectorProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetectorProcessor.cs index 847f3a1c7f..1e69893725 100644 --- a/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetectorProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetectorProcessor.cs @@ -23,13 +23,13 @@ namespace ImageSharp.Processors public abstract float[][] KernelXY { get; } /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { new ConvolutionProcessor(this.KernelXY).Apply(source, sourceRectangle); } /// - protected override void OnApply(ImageBase source, Rectangle sourceRectangle) + protected override void BeforeApply(ImageBase source, Rectangle sourceRectangle) { if (this.Grayscale) { diff --git a/src/ImageSharp/Filters/Processors/Convolution/GaussianBlurProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/GaussianBlurProcessor.cs index 8553e42648..c24b1ef8cd 100644 --- a/src/ImageSharp/Filters/Processors/Convolution/GaussianBlurProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Convolution/GaussianBlurProcessor.cs @@ -81,7 +81,7 @@ namespace ImageSharp.Processors public float[][] KernelY { get; } /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { new Convolution2PassProcessor(this.KernelX, this.KernelY).Apply(source, sourceRectangle); } diff --git a/src/ImageSharp/Filters/Processors/Convolution/GaussianSharpenProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/GaussianSharpenProcessor.cs index 48790a7334..34bd4897e8 100644 --- a/src/ImageSharp/Filters/Processors/Convolution/GaussianSharpenProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Convolution/GaussianSharpenProcessor.cs @@ -83,7 +83,7 @@ namespace ImageSharp.Processors public float[][] KernelY { get; } /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { new Convolution2PassProcessor(this.KernelX, this.KernelY).Apply(source, sourceRectangle); } diff --git a/src/ImageSharp/Filters/Processors/Effects/AlphaProcessor.cs b/src/ImageSharp/Filters/Processors/Effects/AlphaProcessor.cs index ea4f7e44a2..0e589d3284 100644 --- a/src/ImageSharp/Filters/Processors/Effects/AlphaProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Effects/AlphaProcessor.cs @@ -37,9 +37,12 @@ namespace ImageSharp.Processors public int Value { get; } /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { float alpha = this.Value / 100F; + + int startY = sourceRectangle.Y; + int endY = sourceRectangle.Bottom; int startX = sourceRectangle.X; int endX = sourceRectangle.Right; diff --git a/src/ImageSharp/Filters/Processors/Effects/BackgroundColorProcessor.cs b/src/ImageSharp/Filters/Processors/Effects/BackgroundColorProcessor.cs index cc81179f80..cf14375579 100644 --- a/src/ImageSharp/Filters/Processors/Effects/BackgroundColorProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Effects/BackgroundColorProcessor.cs @@ -38,8 +38,10 @@ namespace ImageSharp.Processors public TColor Value { get; } /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { + int startY = sourceRectangle.Y; + int endY = sourceRectangle.Bottom; int startX = sourceRectangle.X; int endX = sourceRectangle.Right; diff --git a/src/ImageSharp/Filters/Processors/Effects/BrightnessProcessor.cs b/src/ImageSharp/Filters/Processors/Effects/BrightnessProcessor.cs index 84cf0c8fbe..c90e6ffdb3 100644 --- a/src/ImageSharp/Filters/Processors/Effects/BrightnessProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Effects/BrightnessProcessor.cs @@ -37,9 +37,12 @@ namespace ImageSharp.Processors public int Value { get; } /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { float brightness = this.Value / 100F; + + int startY = sourceRectangle.Y; + int endY = sourceRectangle.Bottom; int startX = sourceRectangle.X; int endX = sourceRectangle.Right; diff --git a/src/ImageSharp/Filters/Processors/Effects/ContrastProcessor.cs b/src/ImageSharp/Filters/Processors/Effects/ContrastProcessor.cs index 6f63264559..83275e42e0 100644 --- a/src/ImageSharp/Filters/Processors/Effects/ContrastProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Effects/ContrastProcessor.cs @@ -37,9 +37,12 @@ namespace ImageSharp.Processors public int Value { get; } /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { float contrast = (100F + this.Value) / 100F; + + int startY = sourceRectangle.Y; + int endY = sourceRectangle.Bottom; int startX = sourceRectangle.X; int endX = sourceRectangle.Right; Vector4 contrastVector = new Vector4(contrast, contrast, contrast, 1); diff --git a/src/ImageSharp/Filters/Processors/Effects/InvertProcessor.cs b/src/ImageSharp/Filters/Processors/Effects/InvertProcessor.cs index 94f6716da8..55c6908ad5 100644 --- a/src/ImageSharp/Filters/Processors/Effects/InvertProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Effects/InvertProcessor.cs @@ -19,8 +19,10 @@ namespace ImageSharp.Processors where TPacked : struct { /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { + int startY = sourceRectangle.Y; + int endY = sourceRectangle.Bottom; int startX = sourceRectangle.X; int endX = sourceRectangle.Right; Vector3 inverseVector = Vector3.One; diff --git a/src/ImageSharp/Filters/Processors/Effects/OilPaintingProcessor.cs b/src/ImageSharp/Filters/Processors/Effects/OilPaintingProcessor.cs index cddf74af6b..6886fa5c10 100644 --- a/src/ImageSharp/Filters/Processors/Effects/OilPaintingProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Effects/OilPaintingProcessor.cs @@ -48,8 +48,10 @@ namespace ImageSharp.Processors public int BrushSize { get; } /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { + int startY = sourceRectangle.Y; + int endY = sourceRectangle.Bottom; int startX = sourceRectangle.X; int endX = sourceRectangle.Right; int radius = this.BrushSize >> 1; diff --git a/src/ImageSharp/Filters/Processors/Effects/PixelateProcessor.cs b/src/ImageSharp/Filters/Processors/Effects/PixelateProcessor.cs index 17b0450e06..02e74146fb 100644 --- a/src/ImageSharp/Filters/Processors/Effects/PixelateProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Effects/PixelateProcessor.cs @@ -37,8 +37,10 @@ namespace ImageSharp.Processors public int Value { get; } /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { + int startY = sourceRectangle.Y; + int endY = sourceRectangle.Bottom; int startX = sourceRectangle.X; int endX = sourceRectangle.Right; int size = this.Value; diff --git a/src/ImageSharp/Filters/Processors/ImageFilteringProcessor.cs b/src/ImageSharp/Filters/Processors/ImageFilteringProcessor.cs index 23a0a3654f..044b385882 100644 --- a/src/ImageSharp/Filters/Processors/ImageFilteringProcessor.cs +++ b/src/ImageSharp/Filters/Processors/ImageFilteringProcessor.cs @@ -21,9 +21,9 @@ namespace ImageSharp.Processors { try { - this.OnApply(source, sourceRectangle); + this.BeforeApply(source, sourceRectangle); - this.Apply(source, sourceRectangle, sourceRectangle.Y, sourceRectangle.Bottom); + this.OnApply(source, sourceRectangle); this.AfterApply(source, sourceRectangle); } @@ -34,27 +34,25 @@ namespace ImageSharp.Processors } /// - /// Applies the process to the specified portion of the specified at the specified location - /// and with the specified size. + /// This method is called before the process is applied to prepare the processor. /// /// The source image. Cannot be null. /// /// The structure that specifies the portion of the image object to draw. /// - /// The index of the row within the source image to start processing. - /// The index of the row within the source image to end processing. - protected abstract void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY); + protected virtual void BeforeApply(ImageBase source, Rectangle sourceRectangle) + { + } /// - /// This method is called before the process is applied to prepare the processor. + /// Applies the process to the specified portion of the specified at the specified location + /// and with the specified size. /// /// The source image. Cannot be null. /// /// The structure that specifies the portion of the image object to draw. /// - protected virtual void OnApply(ImageBase source, Rectangle sourceRectangle) - { - } + protected abstract void OnApply(ImageBase source, Rectangle sourceRectangle); /// /// This method is called after the process is applied to prepare the processor. diff --git a/src/ImageSharp/Filters/Processors/Overlays/BlendProcessor.cs b/src/ImageSharp/Filters/Processors/Overlays/BlendProcessor.cs index e764879763..fdcc7b1298 100644 --- a/src/ImageSharp/Filters/Processors/Overlays/BlendProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Overlays/BlendProcessor.cs @@ -55,7 +55,7 @@ namespace ImageSharp.Processors public Point Location { get; } /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { if (this.Image.Bounds.Size != this.Size) { @@ -66,8 +66,8 @@ namespace ImageSharp.Processors Rectangle bounds = this.Image.Bounds; int minX = Math.Max(this.Location.X, sourceRectangle.X); int maxX = Math.Min(this.Location.X + bounds.Width, sourceRectangle.Width); - int minY = Math.Max(this.Location.Y, startY); - int maxY = Math.Min(this.Location.Y + bounds.Height, endY); + int minY = Math.Max(this.Location.Y, sourceRectangle.Y); + int maxY = Math.Min(this.Location.Y + bounds.Height, sourceRectangle.Bottom); float alpha = this.Alpha / 100F; diff --git a/src/ImageSharp/Filters/Processors/Overlays/GlowProcessor.cs b/src/ImageSharp/Filters/Processors/Overlays/GlowProcessor.cs index 6b1fe40c2c..d49ad8b849 100644 --- a/src/ImageSharp/Filters/Processors/Overlays/GlowProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Overlays/GlowProcessor.cs @@ -39,8 +39,10 @@ namespace ImageSharp.Processors public float Radius { get; set; } /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { + int startY = sourceRectangle.Y; + int endY = sourceRectangle.Bottom; int startX = sourceRectangle.X; int endX = sourceRectangle.Right; TColor glowColor = this.GlowColor; diff --git a/src/ImageSharp/Filters/Processors/Overlays/VignetteProcessor.cs b/src/ImageSharp/Filters/Processors/Overlays/VignetteProcessor.cs index cdc8019140..87e7d0623f 100644 --- a/src/ImageSharp/Filters/Processors/Overlays/VignetteProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Overlays/VignetteProcessor.cs @@ -44,8 +44,10 @@ namespace ImageSharp.Processors public float RadiusY { get; set; } /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { + int startY = sourceRectangle.Y; + int endY = sourceRectangle.Bottom; int startX = sourceRectangle.X; int endX = sourceRectangle.Right; TColor vignetteColor = this.VignetteColor; diff --git a/src/ImageSharp/Filters/Processors/Transforms/CompandingResizeProcessor.cs b/src/ImageSharp/Filters/Processors/Transforms/CompandingResizeProcessor.cs index 3c6562dc07..3c5bb5e29b 100644 --- a/src/ImageSharp/Filters/Processors/Transforms/CompandingResizeProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Transforms/CompandingResizeProcessor.cs @@ -48,7 +48,7 @@ namespace ImageSharp.Processors public override bool Compand { get; set; } = true; /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { // Jump out, we'll deal with that later. if (source.Width == this.Width && source.Height == this.Height && sourceRectangle == this.ResizeRectangle) @@ -56,12 +56,10 @@ namespace ImageSharp.Processors return; } - // Reset the values as the rectangle can be altered by ResizeRectangle. - startY = this.ResizeRectangle.Y; - endY = this.ResizeRectangle.Bottom; - int width = this.Width; int height = this.Height; + int startY = this.ResizeRectangle.Y; + int endY = this.ResizeRectangle.Bottom; int startX = this.ResizeRectangle.X; int endX = this.ResizeRectangle.Right; diff --git a/src/ImageSharp/Filters/Processors/Transforms/CropProcessor.cs b/src/ImageSharp/Filters/Processors/Transforms/CropProcessor.cs index 1e7916d068..28bdd5ff35 100644 --- a/src/ImageSharp/Filters/Processors/Transforms/CropProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Transforms/CropProcessor.cs @@ -32,15 +32,15 @@ namespace ImageSharp.Processors public Rectangle CropRectangle { get; } /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { if (this.CropRectangle == sourceRectangle) { return; } - int minY = Math.Max(this.CropRectangle.Y, startY); - int maxY = Math.Min(this.CropRectangle.Bottom, endY); + int minY = Math.Max(this.CropRectangle.Y, sourceRectangle.Y); + int maxY = Math.Min(this.CropRectangle.Bottom, sourceRectangle.Bottom); int minX = Math.Max(this.CropRectangle.X, sourceRectangle.X); int maxX = Math.Min(this.CropRectangle.Right, sourceRectangle.Right); diff --git a/src/ImageSharp/Filters/Processors/Transforms/EntropyCropProcessor.cs b/src/ImageSharp/Filters/Processors/Transforms/EntropyCropProcessor.cs index 263c63790c..c4817b9254 100644 --- a/src/ImageSharp/Filters/Processors/Transforms/EntropyCropProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Transforms/EntropyCropProcessor.cs @@ -34,7 +34,7 @@ namespace ImageSharp.Processors public float Value { get; } /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { ImageBase temp = new Image(source.Width, source.Height); temp.ClonePixels(source.Width, source.Height, source.Pixels); diff --git a/src/ImageSharp/Filters/Processors/Transforms/FlipProcessor.cs b/src/ImageSharp/Filters/Processors/Transforms/FlipProcessor.cs index b92333251e..696ca2deb8 100644 --- a/src/ImageSharp/Filters/Processors/Transforms/FlipProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Transforms/FlipProcessor.cs @@ -32,7 +32,7 @@ namespace ImageSharp.Processors public FlipType FlipType { get; } /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { switch (this.FlipType) { diff --git a/src/ImageSharp/Filters/Processors/Transforms/ResamplingWeightedProcessor.cs b/src/ImageSharp/Filters/Processors/Transforms/ResamplingWeightedProcessor.cs index 4f5efff64c..3effbab616 100644 --- a/src/ImageSharp/Filters/Processors/Transforms/ResamplingWeightedProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Transforms/ResamplingWeightedProcessor.cs @@ -69,7 +69,7 @@ namespace ImageSharp.Processors protected Weights[] VerticalWeights { get; set; } /// - protected override void OnApply(ImageBase source, Rectangle sourceRectangle) + protected override void BeforeApply(ImageBase source, Rectangle sourceRectangle) { if (!(this.Sampler is NearestNeighborResampler)) { diff --git a/src/ImageSharp/Filters/Processors/Transforms/ResizeProcessor.cs b/src/ImageSharp/Filters/Processors/Transforms/ResizeProcessor.cs index cf0cf2a8f2..4ffe33ee1f 100644 --- a/src/ImageSharp/Filters/Processors/Transforms/ResizeProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Transforms/ResizeProcessor.cs @@ -47,7 +47,7 @@ namespace ImageSharp.Processors } /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { // Jump out, we'll deal with that later. if (source.Width == this.Width && source.Height == this.Height && sourceRectangle == this.ResizeRectangle) @@ -55,12 +55,10 @@ namespace ImageSharp.Processors return; } - // Reset the values as the rectangle can be altered by ResizeRectangle. - startY = this.ResizeRectangle.Y; - endY = this.ResizeRectangle.Bottom; - int width = this.Width; int height = this.Height; + int startY = this.ResizeRectangle.Y; + int endY = this.ResizeRectangle.Bottom; int startX = this.ResizeRectangle.X; int endX = this.ResizeRectangle.Right; diff --git a/src/ImageSharp/Filters/Processors/Transforms/RotateProcessor.cs b/src/ImageSharp/Filters/Processors/Transforms/RotateProcessor.cs index 2ab16d592b..a6f13ba35a 100644 --- a/src/ImageSharp/Filters/Processors/Transforms/RotateProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Transforms/RotateProcessor.cs @@ -34,7 +34,7 @@ namespace ImageSharp.Processors public bool Expand { get; set; } = true; /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { if (this.OptimizedApply(source)) { @@ -70,7 +70,7 @@ namespace ImageSharp.Processors } /// - protected override void OnApply(ImageBase source, Rectangle sourceRectangle) + protected override void BeforeApply(ImageBase source, Rectangle sourceRectangle) { const float Epsilon = .0001F; diff --git a/src/ImageSharp/Filters/Processors/Transforms/SkewProcessor.cs b/src/ImageSharp/Filters/Processors/Transforms/SkewProcessor.cs index 49aa512542..050fbb06ce 100644 --- a/src/ImageSharp/Filters/Processors/Transforms/SkewProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Transforms/SkewProcessor.cs @@ -39,7 +39,7 @@ namespace ImageSharp.Processors public bool Expand { get; set; } = true; /// - protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { int height = this.CanvasRectangle.Height; int width = this.CanvasRectangle.Width; @@ -70,7 +70,7 @@ namespace ImageSharp.Processors } /// - protected override void OnApply(ImageBase source, Rectangle sourceRectangle) + protected override void BeforeApply(ImageBase source, Rectangle sourceRectangle) { this.processMatrix = Point.CreateSkew(new Point(0, 0), -this.AngleX, -this.AngleY); if (this.Expand) diff --git a/tests/ImageSharp.Tests/Processors/Filters/OilPaintTest.cs b/tests/ImageSharp.Tests/Processors/Filters/OilPaintTest.cs index bb607b839a..970d79a5ae 100644 --- a/tests/ImageSharp.Tests/Processors/Filters/OilPaintTest.cs +++ b/tests/ImageSharp.Tests/Processors/Filters/OilPaintTest.cs @@ -15,8 +15,8 @@ namespace ImageSharp.Tests public static readonly TheoryData> OilPaintValues = new TheoryData> { - new Tuple(15,10), - new Tuple(6,5) + new Tuple(15, 10), + new Tuple(6, 5) }; [Theory] @@ -32,8 +32,11 @@ namespace ImageSharp.Tests using (FileStream output = File.OpenWrite($"{path}/{filename}")) { - image.OilPaint(value.Item1, value.Item2) - .Save(output); + if (image.Width > value.Item2 && image.Height > value.Item2) + { + image.OilPaint(value.Item1, value.Item2) + .Save(output); + } } } } @@ -51,8 +54,10 @@ namespace ImageSharp.Tests using (FileStream output = File.OpenWrite($"{path}/{filename}")) { - image.OilPaint(value.Item1, value.Item2, new Rectangle(10, 10, image.Width / 2, image.Height / 2)) - .Save(output); + if (image.Width > value.Item2 && image.Height > value.Item2) + { + image.OilPaint(value.Item1, value.Item2, new Rectangle(10, 10, image.Width / 2, image.Height / 2)).Save(output); + } } } }