Free Online Image Tools

Edit photos directly in your web browser!

online-image-apps-at-fiveko
Home » Blog » Tutorials » Gaussian filter in pure JavaScript

Gaussian filter in pure JavaScript

This article shows a sample implementation of a separable Gaussian filter in pure Java Script code. This filter finds many applications in various image processing algorithms.

Canvas build ins

Before we move on to the Gaussian part, I think it’s worth mentioning some other JS blurring techniques that work for us in many cases.

Since we are talking about Java Script, it is good to know that HTML5 Canvas element has some built-in filters. An example snippet of Canvas blur looks like this:

const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
const texture = document.querySelector("img");
texture.onload = function(){
  canvas.width = this.width;
  canvas.height = this.height;
  ctx.filter = 'blur(10px)';
  ctx.drawImage(this, 0, 0);
}

Other approaches that work well for the web are CSS and SVG filters and they are compatible with Canvas as well. However, they are not well designed for cases where our code runs in Web Worker.


Gaussian filter source code

Now we can move on to the main part of our topic – Gaussian blurring 🙂

Compute the Gaussian kernel

Initially we prepare an array that holds the Gaussian kernel. In this way, we calculate a Gaussian mask as a lookup table to convolve later our image – once for rows and once for columns.

The makeGaussKernel function creates a one dimensional array with the appropriate filter size and coefficients.


function makeGaussKernel(sigma){
  const GAUSSKERN = 6.0;
  var dim = parseInt(Math.max(3.0, GAUSSKERN * sigma));
  var sqrtSigmaPi2 = Math.sqrt(Math.PI*2.0)*sigma;
  var s2 = 2.0 * sigma * sigma;
  var sum = 0.0;
  
  var kernel = new Float32Array(dim - !(dim & 1)); // Make it odd number
  const half = parseInt(kernel.length / 2);
  for (var j = 0, i = -half; j < kernel.length; i++, j++) 
  {
    kernel[j] = Math.exp(-(i*i)/(s2)) / sqrtSigmaPi2;
    sum += kernel[j];
  }
  // Normalize the gaussian kernel to prevent image darkening/brightening
  for (var i = 0; i < dim; i++) {
    kernel[i] /= sum;
  }
  return kernel;
}

Note that we normalize the kernel values to prevent image darkening/brightening at convolution stage.

Convolution with Gaussian filter

Now we have the blur coefficients from the above steps and it’s time to use them to smooth our photo.

The JavaScript source code below reveals the implementation of separable Gaussian blur by one dimensional convolution. As noted in the article, this approach is more optimal and provides better performance. Therefore, we can divide the blurring process into two steps – horizontal and vertical.

Let’s say we have an image file read into a canvas element. We can apply a separable Gaussian filter to it with the following JavaScript code:

/**
* Internal helper method
* @param pixels - the Canvas pixles
* @param kernel - the Gaussian blur kernel
* @param ch - the color channel to apply the blur on
* @param gray - flag to show RGB or Grayscale image
*/
function gauss_internal(pixels, kernel, ch, gray){
  var data = pixels.data;
  var w = pixels.width;
  var h = pixels.height;
  var buff = new Uint8Array(w*h); 
  var mk = Math.floor(kernel.length / 2);
  var kl = kernel.length;
  
  // First step process columns
  for (var j = 0, hw = 0; j < h; j++, hw += w) 
  {
    for (var i = 0; i < w; i++)
    {
      var sum = 0;
      for (var k = 0; k < kl; k++)
      {
        var col = i + (k - mk);
        col = (col < 0) ? 0 : ((col >= w) ? w - 1 : col);
        sum += data[(hw + col)*4 + ch]*kernel[k];
      }
      buff[hw + i] = sum;
    }
  }
  
  // Second step process rows
  for (var j = 0, offset = 0; j < h; j++, offset += w) 
  {
    for (var i = 0; i < w; i++)
    {
      var sum = 0;
      for (k = 0; k < kl; k++)
      {
        var row = j + (k - mk);
        row = (row < 0) ? 0 : ((row >= h) ? h - 1 : row);
        sum += buff[(row*w + i)]*kernel[k];
      }
      var off = (j*w + i)*4;
      (!gray) ? data[off + ch] = sum : 
                data[off] = data[off + 1] = data[off + 2] = sum;
    }
  }
}

/**
* Gaussian blur example
* @param canvas - HTML5 Canvas element
* @sigma sigma - the standard deviation
*/
function gauss(canvas, sigma){
  var context = canvas.getContext('2d');
  var pixels = context.getImageData(0, 0, canvas.width,canvas.height);
  var kernel = makeGaussKernel(sigma);
  
  // Blur a cahnnel (RGB or Grayscale)
  for (var ch = 0; ch < 3; ch++){
    gauss_internal(pixels, kernel, ch, false);
  }
  // Apply the modified pixels
  context.putImageData(pixels, 0, 0);
}

Once the blurring process is complete, “context.putImageData” places the new pixel data in the canvas element.

Conclusion

This short post, describes how to code the popular Gaussian blur filter using pure Java Script. With this short snippet we can achieve photo smoothing effect online in our browser.

You can visit our other publications and image processing articles.


WEB APPLET

See how it works in the browser!

Image blur effect with Gaussian filter
TAGS:

Spectrum Audio Editor (Free!)

Effortless audio editing, made free. Edit sound like a pro with our online spectrum analyzer.

Sound CMD - Free Online Audio Editor

Fiveko Blog ↗

Discover articles and algorithms for image processing, programming, computer graphics, and more

Image Tools ↗

Free to use online image tools that run in a web browser. Apply photo effects to JPG, PNG, WebP and so on

Projects ↗

Small software projects and applications for various tasks: Graphics, Audio processing and others