了解 JavaScript 灰度算法的工作原理(不使用 jQuery)

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

今天在找一个将彩色图像转为灰度的算法,结果搜索不长就找到了下面这篇文章

3 Ways to Turn Web Images to Grayscale

本文包含以下代码片段

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);

另外在这篇文章中 http://www.ajaxblender.com/howto-convert-image-to-grayscale-using-javascript.html 在评论中有人建议替换:

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;
    }
}

与:

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;
}

JSFiddle 上的演示 https://jsfiddle.net/n6q9a2c9/

我对这个算法的工作原理有一些理解上的问题。

在此代码段中

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;
}

我明白var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3是公式(R + G + B) / 3下面是令我困惑的部分

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

这里为什么要加4?

如果能回答这个算法是如何工作的,我将不胜感激。

Canvas 数据以 RGBA(红、绿、蓝和称为 'alpha' 的透明度值)交错格式提供给您。每个通道每个像素需要一个字节,而您有四个通道,因此每个像素有四个值。由于通道是交错的,因此您递增 4 以步进像素。

参考文献: