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 suggested 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.
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:
getImageData()
)