How to Convolute Images using FabricJS
Convolution filters aren’t commonly heard of. However, you might have come across it in case you worked on image processing projects. Many studies on image processing require the edge detection, blurring or sharpening of images.
This is exactly where convolution filters come into play. The term “Convolution”, in mathematics, can express how the shape of one function is modified by another function.
The Convolute class of FabricJS extends fabric.Image.filters.BaseFilter and it can be called by simply creating an instance of fabric.Image.filters.Convolute.
Edge detection using FabricJS
Let’s see how we can use the Convolute class in order to detect the edges of an image. Edge detection simply means finding the boundaries of an image. Here is the original image that we are going to work with today:
It is absolutely okay to not know something. In case, you don’t know how to add images to the canvas, click here!
Edge detection can be done using filters like Canny, Laplacian, Prewitt, Sobel etc. Here, I have used the Sobel filter matrix. The first matrix calculates the horizontal gradient of the image while the second matrix calculates the vertical gradient. Finally these two are combined in order to compute the edges of the image.
// Applying sobel filter
img.filters.push(
new fabric.Image.filters.Convolute({
matrix: [-1, -2, -1, 0, 0, 0, 1, 2, 1], // horizontal
})
);
img.filters.push(
new fabric.Image.filters.Convolute({
matrix: [-1, 0, 1, -2, 0, 2, -1, 0, 1], // vertical
})
);
// The applyFilters method applies the filter and re-renders the canvas
img.applyFilters();
This is how the complete code is going to look like:
<!DOCTYPE html>
<html>
<head>
<!-- Adding the FabricJS library -->
<script
src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/521/fabric.min.js"
integrity="sha512-nPzvcIhv7AtvjpNcnbr86eT6zGtiudLiLyVssCWLmvQHgR95VvkLX8mMpqNKWs1TG3Hnf+tvHpnGmpPS3yJIgw=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
</head>
<body>
<canvas
id="canvas"
style="border: 2px solid black"
width="400"
height="300"
></canvas>
<script>
var canvas = new fabric.Canvas("canvas", {
backgroundColor: "black",
isDrawingMode: false,
});
// Adding the image to the canvas
fabric.Image.fromURL(
"https://images.unsplash.com/photo-1583795128727-6ec3642408f8?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=757&q=80",
function (img) {
img.scale(0.45);
img.set("top", 15);
img.set("left", 200);
img.set("originX", "center");
img.set("originY", "top");
// Applying sobel filter
img.filters.push(
new fabric.Image.filters.Convolute({
matrix: [-1, -2, -1, 0, 0, 0, 1, 2, 1], // horizontal
})
);
img.filters.push(
new fabric.Image.filters.Convolute({
matrix: [-1, 0, 1, -2, 0, 2, -1, 0, 1], // vertical
})
);
// using applyFilters() method
img.applyFilters();
// Adding the image to the canvas by using the add() method
canvas.add(img);
},
{ crossOrigin: "anonymous" } // Not adding this line will result in exception in the console
);
</script>
</body>
</html>
The output will be:
Image embossing using Convolute class in FabricJS
We can also emboss the above image by using the Convolute class. Embossing an image can be done by replacing each pixel of the image by a highlight or shadow.
Side Note : Pixel- short for Picture Element, is the smallest unit in a digital display. Each pixel consists of a subpixel that emits RGB color. You might know that when the number of pixels is high, it results in a clearer and sharper image and vice versa.
The matrix below is the emboss filter matrix:
matrix: [1, 1, 1, 1, 0.7, -1, -1, -1, -1]
- We can add the emboss filter like so:
// Applying the emboss filter
img.filters.push(
new fabric.Image.filters.Convolute({
matrix: [1, 1, 1, 1, 0.7, -1, -1, -1, -1],
})
);
// using applyFilters() method
img.applyFilters();
// Adding the image to the canvas by using the add() method
canvas.add(img);
Here is the output image:
How to apply Pixelate Effect using FabricJS
We use the pixelate effect in order to make the pixels of an image larger. Why would we want to use the pixelate effect? We use it whenever we want to conceal a part of the image, brand logos or any sensitive information that we might just want to hide from others.
FabricJS provides us the pixelate class which we can leverage to make the pixel size bigger.
- The first step is to add the image to the canvas by using the fromURL() method.
- We initiate an instance of new fabric.Image.filters.Pixelate and assign the blocksize property a Number value in the optional options Object.
- Here is a pixelated image where the blocksize property is passed a value of 10:
When we assign the blocksize property a value of 20, the image looks like this:
You can see the difference in pixel size in both of the above images. We can increase the size of each pixel by changing the value that we are passing to the blocksize property.
// Applying the Pixelate filter
img.filters.push(
new fabric.Image.filters.Pixelate({
blocksize: 20,
})
);
// using applyFilters() method
img.applyFilters();