private static BlurColor GetColor(BlurColor[,] buffer, int x, int y) { x = Math.Max(0, Math.Min(buffer.GetLength(0) - 1, x)); y = Math.Max(0, Math.Min(buffer.GetLength(1) - 1, y)); return buffer[x, y]; }
public static Bitmap Generate(Image image, double sigma) { var scaleFactor = 1.5 * sigma + 1; var kernelWidth = (int)Math.Round((3 * sigma) / scaleFactor); if (kernelWidth == 0) return new Bitmap(image); var kernel = new double[kernelWidth]; for (var i = 0; i < kernelWidth; i++) { var x = i * scaleFactor; kernel[i] = Math.Exp(-x * x / (2 * sigma * sigma)) / (sigma * Math.Sqrt(2 * Math.PI)); } var overallWeight = kernel[0]; for (var i = 1; i < kernelWidth; i++) { overallWeight += 2 * kernel[i]; } var width = (int)Math.Round(image.Width / scaleFactor); var height = (int)Math.Round(image.Height / scaleFactor); var sourceImage = new Bitmap(image, width, height); var resultImage = sourceImage; var sourceBuffer = new BlurColor[width, height]; var tempBuffer = new BlurColor[width, height]; for (var y = 0; y < height; y++) { for (var x = 0; x < width; x++) { sourceBuffer[x, y] = new BlurColor(sourceImage.GetPixel(x, y)); } } for (var y = 0; y < height; y++) { Parallel.For(0, width, x => { var result = kernel[0] * GetColor(sourceBuffer, x, y); for (var i = 1; i < kernelWidth; i++) { var weight = kernel[i]; result += weight * (GetColor(sourceBuffer, x - i, y) + GetColor(sourceBuffer, x + i, y)); } result /= overallWeight; tempBuffer[x, y] = result; }); } for (var y = 0; y < height; y++) { Parallel.For(0, width, x => { var result = kernel[0] * GetColor(tempBuffer, x, y); for (var i = 1; i < kernelWidth; i++) { var weight = kernel[i]; result += weight * (GetColor(tempBuffer, x, y - i) + GetColor(tempBuffer, x, y + i)); } result /= overallWeight; lock (resultImage) { resultImage.SetPixel(x, y, result.ActualColor); } }); } return resultImage; }
public static Bitmap Generate(Image image, double sigma) { var scaleFactor = 1.5 * sigma + 1; var kernelWidth = (int)Round((3 * sigma) / scaleFactor); if (kernelWidth == 0) { return(new Bitmap(image)); } var kernel = new double[kernelWidth]; for (var i = 0; i < kernelWidth; i++) { var x = i * scaleFactor; kernel[i] = Exp(-x * x / (2 * sigma * sigma)) / (sigma * Sqrt(2 * PI)); } var overallWeight = kernel[0]; for (var i = 1; i < kernelWidth; i++) { overallWeight += 2 * kernel[i]; } var width = (int)Round(image.Width / scaleFactor); var height = (int)Round(image.Height / scaleFactor); var sourceImage = new Bitmap(image, width, height); var resultImage = sourceImage; var sourceBuffer = new BlurColor[width, height]; var tempBuffer = new BlurColor[width, height]; for (var y = 0; y < height; y++) { for (var x = 0; x < width; x++) { sourceBuffer[x, y] = new BlurColor(sourceImage.GetPixel(x, y)); } } for (var y = 0; y < height; y++) { Parallel.For(0, width, x => { var result = kernel[0] * GetColor(sourceBuffer, x, y); for (var i = 1; i < kernelWidth; i++) { var weight = kernel[i]; result += weight * (GetColor(sourceBuffer, x - i, y) + GetColor(sourceBuffer, x + i, y)); } result /= overallWeight; tempBuffer[x, y] = result; }); } for (var y = 0; y < height; y++) { Parallel.For(0, width, x => { var result = kernel[0] * GetColor(tempBuffer, x, y); for (var i = 1; i < kernelWidth; i++) { var weight = kernel[i]; result += weight * (GetColor(tempBuffer, x, y - i) + GetColor(tempBuffer, x, y + i)); } result /= overallWeight; lock (resultImage) { resultImage.SetPixel(x, y, result.ActualColor); } }); } return(resultImage); }