diff --git a/src/ImageSharp/Processing/Extensions/Convolution/BoxBlurExtensions.cs b/src/ImageSharp/Processing/Extensions/Convolution/BoxBlurExtensions.cs
index f891ffa97c..a7f93e23ec 100644
--- a/src/ImageSharp/Processing/Extensions/Convolution/BoxBlurExtensions.cs
+++ b/src/ImageSharp/Processing/Extensions/Convolution/BoxBlurExtensions.cs
@@ -39,5 +39,26 @@ namespace SixLabors.ImageSharp.Processing
/// The to allow chaining of operations.
public static IImageProcessingContext BoxBlur(this IImageProcessingContext source, int radius, Rectangle rectangle)
=> source.ApplyProcessor(new BoxBlurProcessor(radius), rectangle);
+
+ ///
+ /// Applies a box blur to the image.
+ ///
+ /// 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 to use when mapping the pixels outside of the border, in X direction.
+ ///
+ ///
+ /// The to use when mapping the pixels outside of the border, in Y direction.
+ ///
+ /// The to allow chaining of operations.
+ public static IImageProcessingContext BoxBlur(this IImageProcessingContext source, int radius, Rectangle rectangle, BorderWrappingMode borderWrapModeX, BorderWrappingMode borderWrapModeY)
+ {
+ var processor = new BoxBlurProcessor(radius, borderWrapModeX, borderWrapModeY);
+ return source.ApplyProcessor(processor, rectangle);
+ }
}
}
diff --git a/src/ImageSharp/Processing/Extensions/Convolution/GaussianBlurExtensions.cs b/src/ImageSharp/Processing/Extensions/Convolution/GaussianBlurExtensions.cs
index bd4fb716d4..49af591e98 100644
--- a/src/ImageSharp/Processing/Extensions/Convolution/GaussianBlurExtensions.cs
+++ b/src/ImageSharp/Processing/Extensions/Convolution/GaussianBlurExtensions.cs
@@ -39,5 +39,26 @@ namespace SixLabors.ImageSharp.Processing
/// The to allow chaining of operations.
public static IImageProcessingContext GaussianBlur(this IImageProcessingContext source, float sigma, Rectangle rectangle)
=> source.ApplyProcessor(new GaussianBlurProcessor(sigma), rectangle);
+
+ ///
+ /// Applies a Gaussian blur to the image.
+ ///
+ /// 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 to use when mapping the pixels outside of the border, in X direction.
+ ///
+ ///
+ /// The to use when mapping the pixels outside of the border, in Y direction.
+ ///
+ /// The to allow chaining of operations.
+ public static IImageProcessingContext GaussianBlur(this IImageProcessingContext source, float sigma, Rectangle rectangle, BorderWrappingMode borderWrapModeX, BorderWrappingMode borderWrapModeY)
+ {
+ var processor = new GaussianBlurProcessor(sigma, borderWrapModeX, borderWrapModeY);
+ return source.ApplyProcessor(processor, rectangle);
+ }
}
}
diff --git a/src/ImageSharp/Processing/Extensions/Convolution/GaussianSharpenExtensions.cs b/src/ImageSharp/Processing/Extensions/Convolution/GaussianSharpenExtensions.cs
index f5b8798f46..5ac9d6909c 100644
--- a/src/ImageSharp/Processing/Extensions/Convolution/GaussianSharpenExtensions.cs
+++ b/src/ImageSharp/Processing/Extensions/Convolution/GaussianSharpenExtensions.cs
@@ -42,5 +42,26 @@ namespace SixLabors.ImageSharp.Processing
float sigma,
Rectangle rectangle) =>
source.ApplyProcessor(new GaussianSharpenProcessor(sigma), rectangle);
+
+ ///
+ /// Applies a Gaussian sharpening filter to the image.
+ ///
+ /// 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 to use when mapping the pixels outside of the border, in X direction.
+ ///
+ ///
+ /// The to use when mapping the pixels outside of the border, in Y direction.
+ ///
+ /// The to allow chaining of operations.
+ public static IImageProcessingContext GaussianSharpen(this IImageProcessingContext source, float sigma, Rectangle rectangle, BorderWrappingMode borderWrapModeX, BorderWrappingMode borderWrapModeY)
+ {
+ var processor = new GaussianSharpenProcessor(sigma, borderWrapModeX, borderWrapModeY);
+ return source.ApplyProcessor(processor, rectangle);
+ }
}
}
diff --git a/src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor.cs
index da6b967181..a622739fd4 100644
--- a/src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor.cs
+++ b/src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor.cs
@@ -21,9 +21,24 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
///
/// The 'radius' value representing the size of the area to sample.
///
- public BoxBlurProcessor(int radius)
+ /// The to use when mapping the pixels outside of the border, in X direction.
+ /// The to use when mapping the pixels outside of the border, in Y direction.
+ public BoxBlurProcessor(int radius, BorderWrappingMode borderWrapModeX, BorderWrappingMode borderWrapModeY)
{
this.Radius = radius;
+ this.BorderWrapModeX = borderWrapModeX;
+ this.BorderWrapModeY = borderWrapModeY;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The 'radius' value representing the size of the area to sample.
+ ///
+ public BoxBlurProcessor(int radius)
+ : this(radius, BorderWrappingMode.Repeat, BorderWrappingMode.Repeat)
+ {
}
///
@@ -39,9 +54,19 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
///
public int Radius { get; }
+ ///
+ /// Gets the to use when mapping the pixels outside of the border, in X direction.
+ ///
+ public BorderWrappingMode BorderWrapModeX { get; }
+
+ ///
+ /// Gets the to use when mapping the pixels outside of the border, in Y direction.
+ ///
+ public BorderWrappingMode BorderWrapModeY { get; }
+
///
public IImageProcessor CreatePixelSpecificProcessor(Configuration configuration, Image source, Rectangle sourceRectangle)
where TPixel : unmanaged, IPixel
- => new BoxBlurProcessor(configuration, this, source, sourceRectangle);
+ => new BoxBlurProcessor(configuration, this, source, sourceRectangle, this.BorderWrapModeX, this.BorderWrapModeY);
}
}
diff --git a/src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor{TPixel}.cs
index 5beadb0cee..ceebdf15aa 100644
--- a/src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor{TPixel}.cs
+++ b/src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor{TPixel}.cs
@@ -27,15 +27,49 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
this.Kernel = CreateBoxKernel(kernelSize);
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The configuration which allows altering default behaviour or extending the library.
+ /// The defining the processor parameters.
+ /// The source for the current processor instance.
+ /// The source area to process for the current processor instance.
+ /// The to use when mapping the pixels outside of the border, in X direction.
+ /// The to use when mapping the pixels outside of the border, in Y direction.
+ public BoxBlurProcessor(
+ Configuration configuration,
+ BoxBlurProcessor definition,
+ Image source,
+ Rectangle sourceRectangle,
+ BorderWrappingMode borderWrapModeX,
+ BorderWrappingMode borderWrapModeY)
+ : base(configuration, source, sourceRectangle)
+ {
+ int kernelSize = (definition.Radius * 2) + 1;
+ this.Kernel = CreateBoxKernel(kernelSize);
+ this.BorderWrapModeX = borderWrapModeX;
+ this.BorderWrapModeY = borderWrapModeY;
+ }
+
///
/// Gets the 1D convolution kernel.
///
public float[] Kernel { get; }
+ ///
+ /// Gets the to use when mapping the pixels outside of the border, in X direction.
+ ///
+ public BorderWrappingMode BorderWrapModeX { get; }
+
+ ///
+ /// Gets the to use when mapping the pixels outside of the border, in Y direction.
+ ///
+ public BorderWrappingMode BorderWrapModeY { get; }
+
///
protected override void OnFrameApply(ImageFrame source)
{
- using var processor = new Convolution2PassProcessor(this.Configuration, this.Kernel, false, this.Source, this.SourceRectangle);
+ using var processor = new Convolution2PassProcessor(this.Configuration, this.Kernel, false, this.Source, this.SourceRectangle, this.BorderWrapModeX, this.BorderWrapModeY);
processor.Apply(source);
}
diff --git a/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor{TPixel}.cs
index fa58422dc6..2fc0a5fe87 100644
--- a/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor{TPixel}.cs
+++ b/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor{TPixel}.cs
@@ -26,16 +26,22 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
/// Whether the convolution filter is applied to alpha as well as the color channels.
/// The source for the current processor instance.
/// The source area to process for the current processor instance.
+ /// The to use when mapping the pixels outside of the border, in X direction.
+ /// The to use when mapping the pixels outside of the border, in Y direction.
public Convolution2PassProcessor(
Configuration configuration,
float[] kernel,
bool preserveAlpha,
Image source,
- Rectangle sourceRectangle)
+ Rectangle sourceRectangle,
+ BorderWrappingMode borderWrapModeX,
+ BorderWrappingMode borderWrapModeY)
: base(configuration, source, sourceRectangle)
{
this.Kernel = kernel;
this.PreserveAlpha = preserveAlpha;
+ this.BorderWrapModeX = borderWrapModeX;
+ this.BorderWrapModeY = borderWrapModeY;
}
///
@@ -48,6 +54,16 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
///
public bool PreserveAlpha { get; }
+ ///
+ /// Gets the to use when mapping the pixels outside of the border, in X direction.
+ ///
+ public BorderWrappingMode BorderWrapModeX { get; }
+
+ ///
+ /// Gets the to use when mapping the pixels outside of the border, in Y direction.
+ ///
+ public BorderWrappingMode BorderWrapModeY { get; }
+
///
protected override void OnFrameApply(ImageFrame source)
{
@@ -63,7 +79,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
// the two 1D kernels represent, and reuse it across both convolution steps, like in the bokeh blur.
using var mapXY = new KernelSamplingMap(this.Configuration.MemoryAllocator);
- mapXY.BuildSamplingOffsetMap(this.Kernel.Length, this.Kernel.Length, interest);
+ mapXY.BuildSamplingOffsetMap(this.Kernel.Length, this.Kernel.Length, interest, this.BorderWrapModeX, this.BorderWrapModeY);
// Horizontal convolution
var horizontalOperation = new HorizontalConvolutionRowOperation(
diff --git a/src/ImageSharp/Processing/Processors/Convolution/GaussianBlurProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/GaussianBlurProcessor.cs
index 1fa65b62cd..3af9791dcb 100644
--- a/src/ImageSharp/Processing/Processors/Convolution/GaussianBlurProcessor.cs
+++ b/src/ImageSharp/Processing/Processors/Convolution/GaussianBlurProcessor.cs
@@ -32,6 +32,17 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
{
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The 'sigma' value representing the weight of the blur.
+ /// The to use when mapping the pixels outside of the border, in X direction.
+ /// The to use when mapping the pixels outside of the border, in Y direction.
+ public GaussianBlurProcessor(float sigma, BorderWrappingMode borderWrapModeX, BorderWrappingMode borderWrapModeY)
+ : this(sigma, ConvolutionProcessorHelpers.GetDefaultGaussianRadius(sigma), borderWrapModeX, borderWrapModeY)
+ {
+ }
+
///
/// Initializes a new instance of the class.
///
@@ -54,9 +65,32 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
/// This should be at least twice the sigma value.
///
public GaussianBlurProcessor(float sigma, int radius)
+ : this(sigma, radius, BorderWrappingMode.Repeat, BorderWrappingMode.Repeat)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The 'sigma' value representing the weight of the blur.
+ ///
+ ///
+ /// The 'radius' value representing the size of the area to sample.
+ /// This should be at least twice the sigma value.
+ ///
+ ///
+ /// The to use when mapping the pixels outside of the border, in X direction.
+ ///
+ ///
+ /// The to use when mapping the pixels outside of the border, in Y direction.
+ ///
+ public GaussianBlurProcessor(float sigma, int radius, BorderWrappingMode borderWrapModeX, BorderWrappingMode borderWrapModeY)
{
this.Sigma = sigma;
this.Radius = radius;
+ this.BorderWrapModeX = borderWrapModeX;
+ this.BorderWrapModeY = borderWrapModeY;
}
///
@@ -69,9 +103,19 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
///
public int Radius { get; }
+ ///
+ /// Gets the to use when mapping the pixels outside of the border, in X direction.
+ ///
+ public BorderWrappingMode BorderWrapModeX { get; }
+
+ ///
+ /// Gets the to use when mapping the pixels outside of the border, in Y direction.
+ ///
+ public BorderWrappingMode BorderWrapModeY { get; }
+
///
public IImageProcessor CreatePixelSpecificProcessor(Configuration configuration, Image source, Rectangle sourceRectangle)
where TPixel : unmanaged, IPixel
- => new GaussianBlurProcessor(configuration, this, source, sourceRectangle);
+ => new GaussianBlurProcessor(configuration, this, source, sourceRectangle, this.BorderWrapModeX, this.BorderWrapModeY);
}
}
diff --git a/src/ImageSharp/Processing/Processors/Convolution/GaussianBlurProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Convolution/GaussianBlurProcessor{TPixel}.cs
index 4ade01f914..16b05b8bb0 100644
--- a/src/ImageSharp/Processing/Processors/Convolution/GaussianBlurProcessor{TPixel}.cs
+++ b/src/ImageSharp/Processing/Processors/Convolution/GaussianBlurProcessor{TPixel}.cs
@@ -30,15 +30,49 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
this.Kernel = ConvolutionProcessorHelpers.CreateGaussianBlurKernel(kernelSize, definition.Sigma);
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The configuration which allows altering default behaviour or extending the library.
+ /// The defining the processor parameters.
+ /// The source for the current processor instance.
+ /// The source area to process for the current processor instance.
+ /// The to use when mapping the pixels outside of the border, in X direction.
+ /// The to use when mapping the pixels outside of the border, in Y direction.
+ public GaussianBlurProcessor(
+ Configuration configuration,
+ GaussianBlurProcessor definition,
+ Image source,
+ Rectangle sourceRectangle,
+ BorderWrappingMode borderWrapModeX,
+ BorderWrappingMode borderWrapModeY)
+ : base(configuration, source, sourceRectangle)
+ {
+ int kernelSize = (definition.Radius * 2) + 1;
+ this.Kernel = ConvolutionProcessorHelpers.CreateGaussianBlurKernel(kernelSize, definition.Sigma);
+ this.BorderWrapModeX = borderWrapModeX;
+ this.BorderWrapModeY = borderWrapModeY;
+ }
+
///
/// Gets the 1D convolution kernel.
///
public float[] Kernel { get; }
+ ///
+ /// Gets the to use when mapping the pixels outside of the border, in X direction.
+ ///
+ public BorderWrappingMode BorderWrapModeX { get; }
+
+ ///
+ /// Gets the to use when mapping the pixels outside of the border, in Y direction.
+ ///
+ public BorderWrappingMode BorderWrapModeY { get; }
+
///
protected override void OnFrameApply(ImageFrame source)
{
- using var processor = new Convolution2PassProcessor(this.Configuration, this.Kernel, false, this.Source, this.SourceRectangle);
+ using var processor = new Convolution2PassProcessor(this.Configuration, this.Kernel, false, this.Source, this.SourceRectangle, this.BorderWrapModeX, this.BorderWrapModeY);
processor.Apply(source);
}
diff --git a/src/ImageSharp/Processing/Processors/Convolution/GaussianSharpenProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/GaussianSharpenProcessor.cs
index 7e1f029066..98c897c21e 100644
--- a/src/ImageSharp/Processing/Processors/Convolution/GaussianSharpenProcessor.cs
+++ b/src/ImageSharp/Processing/Processors/Convolution/GaussianSharpenProcessor.cs
@@ -32,6 +32,17 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
{
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The 'sigma' value representing the weight of the blur.
+ /// The to use when mapping the pixels outside of the border, in X direction.
+ /// The to use when mapping the pixels outside of the border, in Y direction.
+ public GaussianSharpenProcessor(float sigma, BorderWrappingMode borderWrapModeX, BorderWrappingMode borderWrapModeY)
+ : this(sigma, ConvolutionProcessorHelpers.GetDefaultGaussianRadius(sigma), borderWrapModeX, borderWrapModeY)
+ {
+ }
+
///
/// Initializes a new instance of the class.
///
@@ -54,9 +65,32 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
/// This should be at least twice the sigma value.
///
public GaussianSharpenProcessor(float sigma, int radius)
+ : this(sigma, radius, BorderWrappingMode.Repeat, BorderWrappingMode.Repeat)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The 'sigma' value representing the weight of the blur.
+ ///
+ ///
+ /// The 'radius' value representing the size of the area to sample.
+ /// This should be at least twice the sigma value.
+ ///
+ ///
+ /// The to use when mapping the pixels outside of the border, in X direction.
+ ///
+ ///
+ /// The to use when mapping the pixels outside of the border, in Y direction.
+ ///
+ public GaussianSharpenProcessor(float sigma, int radius, BorderWrappingMode borderWrapModeX, BorderWrappingMode borderWrapModeY)
{
this.Sigma = sigma;
this.Radius = radius;
+ this.BorderWrapModeX = borderWrapModeX;
+ this.BorderWrapModeY = borderWrapModeY;
}
///
@@ -69,9 +103,19 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
///
public int Radius { get; }
+ ///
+ /// Gets the to use when mapping the pixels outside of the border, in X direction.
+ ///
+ public BorderWrappingMode BorderWrapModeX { get; }
+
+ ///
+ /// Gets the to use when mapping the pixels outside of the border, in Y direction.
+ ///
+ public BorderWrappingMode BorderWrapModeY { get; }
+
///
public IImageProcessor CreatePixelSpecificProcessor(Configuration configuration, Image source, Rectangle sourceRectangle)
where TPixel : unmanaged, IPixel
- => new GaussianSharpenProcessor(configuration, this, source, sourceRectangle);
+ => new GaussianSharpenProcessor(configuration, this, source, sourceRectangle, this.BorderWrapModeX, this.BorderWrapModeY);
}
}
diff --git a/src/ImageSharp/Processing/Processors/Convolution/GaussianSharpenProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Convolution/GaussianSharpenProcessor{TPixel}.cs
index 73aaaec188..bddaab233b 100644
--- a/src/ImageSharp/Processing/Processors/Convolution/GaussianSharpenProcessor{TPixel}.cs
+++ b/src/ImageSharp/Processing/Processors/Convolution/GaussianSharpenProcessor{TPixel}.cs
@@ -16,7 +16,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
/// Initializes a new instance of the class.
///
/// The configuration which allows altering default behaviour or extending the library.
- /// The defining the processor parameters.
+ /// The defining the processor parameters.
/// The source for the current processor instance.
/// The source area to process for the current processor instance.
public GaussianSharpenProcessor(
@@ -24,10 +24,32 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
GaussianSharpenProcessor definition,
Image source,
Rectangle sourceRectangle)
+ : this(configuration, definition, source, sourceRectangle, BorderWrappingMode.Repeat, BorderWrappingMode.Repeat)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The configuration which allows altering default behaviour or extending the library.
+ /// The defining the processor parameters.
+ /// The source for the current processor instance.
+ /// The source area to process for the current processor instance.
+ /// The to use when mapping the pixels outside of the border, in X direction.
+ /// The to use when mapping the pixels outside of the border, in Y direction.
+ public GaussianSharpenProcessor(
+ Configuration configuration,
+ GaussianSharpenProcessor definition,
+ Image source,
+ Rectangle sourceRectangle,
+ BorderWrappingMode borderWrapModeX,
+ BorderWrappingMode borderWrapModeY)
: base(configuration, source, sourceRectangle)
{
int kernelSize = (definition.Radius * 2) + 1;
this.Kernel = ConvolutionProcessorHelpers.CreateGaussianSharpenKernel(kernelSize, definition.Sigma);
+ this.BorderWrapModeX = borderWrapModeX;
+ this.BorderWrapModeY = borderWrapModeY;
}
///
@@ -35,10 +57,20 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
///
public float[] Kernel { get; }
+ ///
+ /// Gets the to use when mapping the pixels outside of the border, in X direction.
+ ///
+ public BorderWrappingMode BorderWrapModeX { get; }
+
+ ///
+ /// Gets the to use when mapping the pixels outside of the border, in Y direction.
+ ///
+ public BorderWrappingMode BorderWrapModeY { get; }
+
///
protected override void OnFrameApply(ImageFrame source)
{
- using var processor = new Convolution2PassProcessor(this.Configuration, this.Kernel, false, this.Source, this.SourceRectangle);
+ using var processor = new Convolution2PassProcessor(this.Configuration, this.Kernel, false, this.Source, this.SourceRectangle, this.BorderWrapModeX, this.BorderWrapModeY);
processor.Apply(source);
}