// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // namespace ImageSharp.Processing { using System; /// /// Applies a Box blur sampler to the image. /// /// The pixel format. public class BoxBlurProcessor : ImageProcessor where TColor : struct, IPackedPixel, IEquatable { /// /// The maximum size of the kernel in either direction. /// private readonly int kernelSize; /// /// Initializes a new instance of the class. /// /// /// The 'radius' value representing the size of the area to sample. /// public BoxBlurProcessor(int radius = 7) { this.kernelSize = (radius * 2) + 1; this.KernelX = this.CreateBoxKernel(true); this.KernelY = this.CreateBoxKernel(false); } /// /// Gets the horizontal gradient operator. /// public float[][] KernelX { get; } /// /// Gets the vertical gradient operator. /// public float[][] KernelY { get; } /// protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { new Convolution2PassProcessor(this.KernelX, this.KernelY).Apply(source, sourceRectangle); } /// /// Create a 1 dimensional Box kernel. /// /// Whether to calculate a horizontal kernel. /// The private float[][] CreateBoxKernel(bool horizontal) { int size = this.kernelSize; float[][] kernel = horizontal ? new float[1][] : new float[size][]; if (horizontal) { kernel[0] = new float[size]; } float sum = 0.0f; for (int i = 0; i < size; i++) { float x = 1; sum += x; if (horizontal) { kernel[0][i] = x; } else { kernel[i] = new[] { x }; } } // Normalise kernel so that the sum of all weights equals 1 if (horizontal) { for (int i = 0; i < size; i++) { kernel[0][i] = kernel[0][i] / sum; } } else { for (int i = 0; i < size; i++) { kernel[i][0] = kernel[i][0] / sum; } } return kernel; } } }