diff --git a/src/ImageSharp/Processing/BoxBlurExtensions.cs b/src/ImageSharp/Processing/BoxBlurExtensions.cs
index 624da239b..bc6e06dd6 100644
--- a/src/ImageSharp/Processing/BoxBlurExtensions.cs
+++ b/src/ImageSharp/Processing/BoxBlurExtensions.cs
@@ -8,43 +8,37 @@ using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing
{
///
- /// Adds box blurring extensions to the type.
+ /// Adds box blurring extensions to the type.
///
public static class BoxBlurExtensions
{
///
/// Applies a box blur to the image.
///
- /// The pixel format.
/// The image this method extends.
/// The .
- public static IImageProcessingContext BoxBlur(this IImageProcessingContext source)
- where TPixel : struct, IPixel
- => source.ApplyProcessor(new BoxBlurProcessor());
+ public static IImageProcessingContext BoxBlur(this IImageProcessingContext source)
+ => source.ApplyProcessor(new BoxBlurProcessor());
///
/// Applies a box blur to the image.
///
- /// The pixel format.
/// The image this method extends.
/// The 'radius' value representing the size of the area to sample.
/// The .
- public static IImageProcessingContext BoxBlur(this IImageProcessingContext source, int radius)
- where TPixel : struct, IPixel
- => source.ApplyProcessor(new BoxBlurProcessor(radius));
+ public static IImageProcessingContext BoxBlur(this IImageProcessingContext source, int radius)
+ => source.ApplyProcessor(new BoxBlurProcessor(radius));
///
/// Applies a box blur to the image.
///
- /// The pixel format.
/// The image this method extends.
/// The 'radius' value representing the size of the area to sample.
///
/// The structure that specifies the portion of the image object to alter.
///
/// The .
- public static IImageProcessingContext BoxBlur(this IImageProcessingContext source, int radius, Rectangle rectangle)
- where TPixel : struct, IPixel
- => source.ApplyProcessor(new BoxBlurProcessor(radius), rectangle);
+ public static IImageProcessingContext BoxBlur(this IImageProcessingContext source, int radius, Rectangle rectangle)
+ => source.ApplyProcessor(new BoxBlurProcessor(radius), rectangle);
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Processing/GaussianBlurExtensions.cs b/src/ImageSharp/Processing/GaussianBlurExtensions.cs
index 165c4ce1a..1dab05457 100644
--- a/src/ImageSharp/Processing/GaussianBlurExtensions.cs
+++ b/src/ImageSharp/Processing/GaussianBlurExtensions.cs
@@ -8,43 +8,37 @@ using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing
{
///
- /// Adds Gaussian blurring extensions to the type.
+ /// Adds Gaussian blurring extensions to the type.
///
public static class GaussianBlurExtensions
{
///
/// Applies a Gaussian blur to the image.
///
- /// The pixel format.
/// The image this method extends.
/// The .
- public static IImageProcessingContext GaussianBlur(this IImageProcessingContext source)
- where TPixel : struct, IPixel
- => source.ApplyProcessor(new GaussianBlurProcessor());
+ public static IImageProcessingContext GaussianBlur(this IImageProcessingContext source)
+ => source.ApplyProcessor(new GaussianBlurProcessor());
///
/// Applies a Gaussian blur to the image.
///
- /// The pixel format.
/// The image this method extends.
/// The 'sigma' value representing the weight of the blur.
/// The .
- public static IImageProcessingContext GaussianBlur(this IImageProcessingContext source, float sigma)
- where TPixel : struct, IPixel
- => source.ApplyProcessor(new GaussianBlurProcessor(sigma));
+ public static IImageProcessingContext GaussianBlur(this IImageProcessingContext source, float sigma)
+ => source.ApplyProcessor(new GaussianBlurProcessor(sigma));
///
/// Applies a Gaussian blur to the image.
///
- /// The pixel format.
/// The image this method extends.
/// The 'sigma' value representing the weight of the blur.
///
/// The structure that specifies the portion of the image object to alter.
///
/// The .
- public static IImageProcessingContext GaussianBlur(this IImageProcessingContext source, float sigma, Rectangle rectangle)
- where TPixel : struct, IPixel
- => source.ApplyProcessor(new GaussianBlurProcessor(sigma), rectangle);
+ public static IImageProcessingContext GaussianBlur(this IImageProcessingContext source, float sigma, Rectangle rectangle)
+ => source.ApplyProcessor(new GaussianBlurProcessor(sigma), rectangle);
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor.cs
index 3d5bdc42a..bb37489e1 100644
--- a/src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor.cs
+++ b/src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor.cs
@@ -3,67 +3,48 @@
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Primitives;
-using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing.Processors.Convolution
{
///
- /// Applies box blur processing to the image.
+ /// Defines a box blur processor of a given Radius.
///
- /// The pixel format.
- internal class BoxBlurProcessor : ImageProcessor
- where TPixel : struct, IPixel
+ public class BoxBlurProcessor : IImageProcessor
{
///
- /// The maximum size of the kernel in either direction.
+ /// The default radius used by the parameterless constructor.
///
- private readonly int kernelSize;
+ public const int DefaultRadius = 7;
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
///
/// The 'radius' value representing the size of the area to sample.
///
- public BoxBlurProcessor(int radius = 7)
+ public BoxBlurProcessor(int radius)
{
this.Radius = radius;
- this.kernelSize = (radius * 2) + 1;
- this.KernelX = this.CreateBoxKernel();
- this.KernelY = this.KernelX.Transpose();
}
///
- /// Gets the Radius
+ /// Initializes a new instance of the class.
///
- public int Radius { get; }
-
- ///
- /// Gets the horizontal gradient operator.
- ///
- public DenseMatrix KernelX { get; }
+ public BoxBlurProcessor()
+ : this(DefaultRadius)
+ {
+ }
///
- /// Gets the vertical gradient operator.
+ /// Gets the Radius.
///
- public DenseMatrix KernelY { get; }
-
- ///
- protected override void OnFrameApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration)
- => new Convolution2PassProcessor(this.KernelX, this.KernelY, false).Apply(source, sourceRectangle, configuration);
+ public int Radius { get; }
- ///
- /// Create a 1 dimensional Box kernel.
- ///
- /// The
- private DenseMatrix CreateBoxKernel()
+ ///
+ public IImageProcessor CreatePixelSpecificProcessor()
+ where TPixel : struct, IPixel
{
- int size = this.kernelSize;
- var kernel = new DenseMatrix(size, 1);
-
- kernel.Fill(1F / size);
-
- return kernel;
+ return new BoxBlurProcessor(this);
}
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor{TPixel}.cs
new file mode 100644
index 000000000..ba092cb42
--- /dev/null
+++ b/src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor{TPixel}.cs
@@ -0,0 +1,64 @@
+// // Copyright (c) Six Labors and contributors.
+// // Licensed under the Apache License, Version 2.0.
+
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.ImageSharp.Primitives;
+using SixLabors.Primitives;
+
+namespace SixLabors.ImageSharp.Processing.Processors.Convolution
+{
+ ///
+ /// Applies box blur processing to the image.
+ ///
+ /// The pixel format.
+ internal class BoxBlurProcessor : ImageProcessor
+ where TPixel : struct, IPixel
+ {
+ private readonly BoxBlurProcessor definition;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The defining the processor parameters.
+ public BoxBlurProcessor(BoxBlurProcessor definition)
+ {
+ this.definition = definition;
+ int kernelSize = (definition.Radius * 2) + 1;
+ this.KernelX = CreateBoxKernel(kernelSize);
+ this.KernelY = this.KernelX.Transpose();
+ }
+
+ ///
+ /// Gets the horizontal gradient operator.
+ ///
+ public DenseMatrix KernelX { get; }
+
+ ///
+ /// Gets the vertical gradient operator.
+ ///
+ public DenseMatrix KernelY { get; }
+
+
+ ///
+ protected override void OnFrameApply(
+ ImageFrame source,
+ Rectangle sourceRectangle,
+ Configuration configuration) =>
+ new Convolution2PassProcessor(this.KernelX, this.KernelY, false).Apply(
+ source,
+ sourceRectangle,
+ configuration);
+
+ ///
+ /// Create a 1 dimensional Box kernel.
+ ///
+ /// The maximum size of the kernel in either direction.
+ /// The .
+ private static DenseMatrix CreateBoxKernel(int kernelSize)
+ {
+ var kernel = new DenseMatrix(kernelSize, 1);
+ kernel.Fill(1F / kernelSize);
+ return kernel;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp/Processing/Processors/Convolution/GaussianBlurProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/GaussianBlurProcessor.cs
index 0fc822d57..33e2ef955 100644
--- a/src/ImageSharp/Processing/Processors/Convolution/GaussianBlurProcessor.cs
+++ b/src/ImageSharp/Processing/Processors/Convolution/GaussianBlurProcessor.cs
@@ -4,35 +4,38 @@
using System;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Primitives;
-using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing.Processors.Convolution
{
///
- /// Applies Gaussian blur processing to the image.
+ /// Defines a gaussian blur processor with a (Sigma, Radius) pair.
///
- /// The pixel format.
- internal class GaussianBlurProcessor : ImageProcessor
- where TPixel : struct, IPixel
+ public class GaussianBlurProcessor : IImageProcessor
{
///
- /// The maximum size of the kernel in either direction.
+ /// The default value for .
///
- private readonly int kernelSize;
+ public const float DefaultSigma = 3f;
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
+ ///
+ public GaussianBlurProcessor()
+ : this(DefaultSigma, CalculateDefaultRadius(DefaultSigma))
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
///
/// The 'sigma' value representing the weight of the blur.
- public GaussianBlurProcessor(float sigma = 3F)
- : this(sigma, (int)MathF.Ceiling(sigma * 3))
+ public GaussianBlurProcessor(float sigma)
+ : this(sigma, CalculateDefaultRadius(sigma))
{
- // Kernel radius is calculated using the minimum viable value.
- // http://chemaguerra.com/gaussian-filter-radius/
}
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
///
/// The 'radius' value representing the size of the area to sample.
@@ -43,7 +46,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
}
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
///
/// The 'sigma' value representing the weight of the blur.
@@ -54,10 +57,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
///
public GaussianBlurProcessor(float sigma, int radius)
{
- this.kernelSize = (radius * 2) + 1;
this.Sigma = sigma;
- this.KernelX = this.CreateGaussianKernel();
- this.KernelY = this.KernelX.Transpose();
+ this.Radius = radius;
}
///
@@ -66,47 +67,24 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
public float Sigma { get; }
///
- /// Gets the horizontal gradient operator.
- ///
- public DenseMatrix KernelX { get; }
-
- ///
- /// Gets the vertical gradient operator.
+ /// Gets the radius defining the size of the area to sample.
///
- public DenseMatrix KernelY { get; }
+ public int Radius { get; }
- ///
- protected override void OnFrameApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration)
- => new Convolution2PassProcessor(this.KernelX, this.KernelY, false).Apply(source, sourceRectangle, configuration);
+ ///
+ public IImageProcessor CreatePixelSpecificProcessor()
+ where TPixel : struct, IPixel
+ {
+ return new GaussianBlurProcessor(this);
+ }
///
- /// Create a 1 dimensional Gaussian kernel using the Gaussian G(x) function
+ /// Kernel radius is calculated using the minimum viable value.
+ /// .
///
- /// The
- private DenseMatrix CreateGaussianKernel()
+ private static int CalculateDefaultRadius(float sigma)
{
- int size = this.kernelSize;
- float weight = this.Sigma;
- var kernel = new DenseMatrix(size, 1);
-
- float sum = 0F;
- float midpoint = (size - 1) / 2F;
-
- for (int i = 0; i < size; i++)
- {
- float x = i - midpoint;
- float gx = ImageMaths.Gaussian(x, weight);
- sum += gx;
- kernel[0, i] = gx;
- }
-
- // Normalize kernel so that the sum of all weights equals 1
- for (int i = 0; i < size; i++)
- {
- kernel[0, i] /= sum;
- }
-
- return kernel;
+ return (int)MathF.Ceiling(sigma * 3);
}
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Processing/Processors/Convolution/GaussianBlurProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Convolution/GaussianBlurProcessor{TPixel}.cs
new file mode 100644
index 000000000..9b60fb2d2
--- /dev/null
+++ b/src/ImageSharp/Processing/Processors/Convolution/GaussianBlurProcessor{TPixel}.cs
@@ -0,0 +1,79 @@
+// // Copyright (c) Six Labors and contributors.
+// // Licensed under the Apache License, Version 2.0.
+
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.ImageSharp.Primitives;
+using SixLabors.Primitives;
+
+namespace SixLabors.ImageSharp.Processing.Processors.Convolution
+{
+ ///
+ /// Applies Gaussian blur processing to an image.
+ ///
+ /// The pixel format.
+ internal class GaussianBlurProcessor : ImageProcessor
+ where TPixel : struct, IPixel
+ {
+ private readonly GaussianBlurProcessor definition;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The defining the processor parameters.
+ public GaussianBlurProcessor(GaussianBlurProcessor definition)
+ {
+ this.definition = definition;
+ int kernelSize = (definition.Radius * 2) + 1;
+ this.KernelX = CreateGaussianKernel(kernelSize, definition.Sigma);
+ this.KernelY = this.KernelX.Transpose();
+ }
+
+ ///
+ /// Gets the horizontal gradient operator.
+ ///
+ public DenseMatrix KernelX { get; }
+
+ ///
+ /// Gets the vertical gradient operator.
+ ///
+ public DenseMatrix KernelY { get; }
+
+ ///
+ protected override void OnFrameApply(
+ ImageFrame source,
+ Rectangle sourceRectangle,
+ Configuration configuration) =>
+ new Convolution2PassProcessor(this.KernelX, this.KernelY, false).Apply(
+ source,
+ sourceRectangle,
+ configuration);
+
+ ///
+ /// Create a 1 dimensional Gaussian kernel using the Gaussian G(x) function
+ ///
+ /// The
+ private static DenseMatrix CreateGaussianKernel(int size, float weight)
+ {
+ var kernel = new DenseMatrix(size, 1);
+
+ float sum = 0F;
+ float midpoint = (size - 1) / 2F;
+
+ for (int i = 0; i < size; i++)
+ {
+ float x = i - midpoint;
+ float gx = ImageMaths.Gaussian(x, weight);
+ sum += gx;
+ kernel[0, i] = gx;
+ }
+
+ // Normalize kernel so that the sum of all weights equals 1
+ for (int i = 0; i < size; i++)
+ {
+ kernel[0, i] /= sum;
+ }
+
+ return kernel;
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Processing/Convolution/BoxBlurTest.cs b/tests/ImageSharp.Tests/Processing/Convolution/BoxBlurTest.cs
index e425b6315..8c659848f 100644
--- a/tests/ImageSharp.Tests/Processing/Convolution/BoxBlurTest.cs
+++ b/tests/ImageSharp.Tests/Processing/Convolution/BoxBlurTest.cs
@@ -14,7 +14,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Convolution
public void BoxBlur_BoxBlurProcessorDefaultsSet()
{
this.operations.BoxBlur();
- var processor = this.Verify>();
+ var processor = this.Verify();
Assert.Equal(7, processor.Radius);
}
@@ -23,7 +23,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Convolution
public void BoxBlur_amount_BoxBlurProcessorDefaultsSet()
{
this.operations.BoxBlur(34);
- var processor = this.Verify>();
+ var processor = this.Verify();
Assert.Equal(34, processor.Radius);
}
@@ -32,7 +32,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Convolution
public void BoxBlur_amount_rect_BoxBlurProcessorDefaultsSet()
{
this.operations.BoxBlur(5, this.rect);
- var processor = this.Verify>(this.rect);
+ var processor = this.Verify(this.rect);
Assert.Equal(5, processor.Radius);
}
diff --git a/tests/ImageSharp.Tests/Processing/Convolution/GaussianBlurTest.cs b/tests/ImageSharp.Tests/Processing/Convolution/GaussianBlurTest.cs
index c87a834eb..0f64ebbeb 100644
--- a/tests/ImageSharp.Tests/Processing/Convolution/GaussianBlurTest.cs
+++ b/tests/ImageSharp.Tests/Processing/Convolution/GaussianBlurTest.cs
@@ -14,7 +14,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Convolution
public void GaussianBlur_GaussianBlurProcessorDefaultsSet()
{
this.operations.GaussianBlur();
- var processor = this.Verify>();
+ var processor = this.Verify();
Assert.Equal(3f, processor.Sigma);
}
@@ -23,7 +23,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Convolution
public void GaussianBlur_amount_GaussianBlurProcessorDefaultsSet()
{
this.operations.GaussianBlur(0.2f);
- var processor = this.Verify>();
+ var processor = this.Verify();
Assert.Equal(.2f, processor.Sigma);
}
@@ -32,7 +32,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Convolution
public void GaussianBlur_amount_rect_GaussianBlurProcessorDefaultsSet()
{
this.operations.GaussianBlur(0.6f, this.rect);
- var processor = this.Verify>(this.rect);
+ var processor = this.Verify(this.rect);
Assert.Equal(.6f, processor.Sigma);
}