gaussianBlur static method

Uint8List gaussianBlur(
  1. Uint8List gray,
  2. int width,
  3. int height, {
  4. int kernelSize = 3,
  5. double sigma = 0,
})

Applies Gaussian blur with configurable kernel size.

gray — Single-channel grayscale pixel buffer. width, height — Image dimensions. kernelSize — Must be odd (3, 5, 7). Default: 3. sigma — Gaussian standard deviation. If 0, computed from kernel size.

Returns the blurred image.

Implementation

static Uint8List gaussianBlur(
  Uint8List gray,
  int width,
  int height, {
  int kernelSize = 3,
  double sigma = 0,
}) {
  if (gray.length < width * height || width < kernelSize || height < kernelSize) {
    return Uint8List.fromList(gray);
  }

  // Ensure odd kernel size
  final k = kernelSize | 1;
  final half = k ~/ 2;

  // Compute sigma if not specified
  final s = sigma > 0 ? sigma : 0.3 * ((k - 1) * 0.5 - 1) + 0.8;

  // Generate 1D Gaussian kernel (separable for performance)
  final kernel = Float64List(k);
  double kernelSum = 0;
  for (int i = 0; i < k; i++) {
    final x = (i - half).toDouble();
    kernel[i] = math.exp(-(x * x) / (2 * s * s));
    kernelSum += kernel[i];
  }
  // Normalize
  for (int i = 0; i < k; i++) {
    kernel[i] /= kernelSum;
  }

  // Separable convolution: horizontal pass
  final temp = Float64List(width * height);
  for (int y = 0; y < height; y++) {
    final row = y * width;
    for (int x = 0; x < width; x++) {
      double sum = 0;
      for (int kx = -half; kx <= half; kx++) {
        final sx = (x + kx).clamp(0, width - 1);
        sum += gray[row + sx] * kernel[kx + half];
      }
      temp[row + x] = sum;
    }
  }

  // Separable convolution: vertical pass
  final result = Uint8List(width * height);
  for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
      double sum = 0;
      for (int ky = -half; ky <= half; ky++) {
        final sy = (y + ky).clamp(0, height - 1);
        sum += temp[sy * width + x] * kernel[ky + half];
      }
      result[y * width + x] = sum.round().clamp(0, 255);
    }
  }

  return result;
}