Mikhail Mikhail - 2 months ago 18
Javascript Question

Understand how to JavaScript Grayscale Algorithm works (without use jQuery)

Today I was looking for an algorithm that converts the color image to grayscale, and the result is not a long search I found the following article

3 Ways to Turn Web Images to Grayscale

This article contains the following code snippet

var imgObj = document.getElementById('js-image');

function gray(imgObj) {
var canvas = document.createElement('canvas');
var canvasContext = canvas.getContext('2d');

var imgW = imgObj.width;
var imgH = imgObj.height;
canvas.width = imgW;
canvas.height = imgH;

canvasContext.drawImage(imgObj, 0, 0);
var imgPixels = canvasContext.getImageData(0, 0, imgW, imgH);

for (var y = 0; y < imgPixels.height; y++) {
for (var x = 0; x < imgPixels.width; x++) {
var i = (y * 4) * imgPixels.width + x * 4;
var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
imgPixels.data[i] = avg;
imgPixels.data[i + 1] = avg;
imgPixels.data[i + 2] = avg;
}
}
canvasContext.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height);
return canvas.toDataURL();
}
imgObj.src = gray(imgObj);


Also in this article http://www.ajaxblender.com/howto-convert-image-to-grayscale-using-javascript.html in comments it was invited to replace

for (var y = 0; y < imgPixels.height; y++) {
for (var x = 0; x < imgPixels.width; x++) {
var i = (y * 4) * imgPixels.width + x * 4;
var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
imgPixels.data[i] = avg;
imgPixels.data[i + 1] = avg;
imgPixels.data[i + 2] = avg;
}
}


with

for (var i = 0; i < imgPixels.data.length; i = i + 4) {
var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
imgPixels.data[i] = avg;
imgPixels.data[i + 1] = avg;
imgPixels.data[i + 2] = avg;
}


Demo on JSFiddle https://jsfiddle.net/n6q9a2c9/

And I have some problems with the understanding of how this algorithm works.

In this code snippet

for (var i = 0; i < imgPixels.data.length; i = i + 4) {
var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
imgPixels.data[i] = avg;
imgPixels.data[i + 1] = avg;
imgPixels.data[i + 2] = avg;
}


I understand that
var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3
is formula
(R + G + B) / 3
below is the part that is confusing to me

for (var i = 0; i < imgPixels.data.length; i = i + 4) {


Why here we increment by 4?

I will be grateful if answer how this algorithm works.

Answer

Canvas data is provided to you in RGBA (red, green, blue, and a transparency value called 'alpha') interleaved format. Each channel needs a byte per pixel and you have four channels and so there are four values per pixel. Since the channels are interleaved, you increment by 4 to step through the pixels.

References:

Comments