Nikolay Dyankov
Nikolay Dyankov

Reputation: 7234

Making a blur algorithm work with canvas image data?

I have the following simple blur algorithm:

for (y = 0; y < height; ++y) {
    for (x = 0; x < width; ++x) {
        total = 0
            for (ky = -radius; ky <= radius; ++ky)
                for (kx = -radius; kx <= radius; ++kx)
                    total += source(x + kx, y + ky)
            dest(x, y) = total / (radius * 2 + 1) ^ 2  
        }
    }

And I need to make this work with an array, generated by canvas with getImageData(). The problem is that the array from canvas is one dimentional, and the algorithm needs a two dimentional one, because "kx" and "ky" are distances from the current pixel, and in a two dimentional array you just change one of the indexes in order to move left or right on the grid, but in a one dimentional array (which is trying to represent a two-dim. one) you can't do that.

What do you think, how should I approach this problem? In my opinion, the entire problem is here:

total += source(x + kx, y + ky)

This line needs to get the correct pixels from the one-dimentional array and it should work fine.

P.S. I forgot to say that I'm trying to blur the image one channel at a time, like this:

for (var i=0; i<imgData.data.length; i+=4) {
    red[index] = imgData.data[i];
    green[index] = imgData.data[i+1];
    blue[index] = imgData.data[i+2];

    index++;
}

and I'm passing each array (red, green and blue) individually to the algorithm.

Upvotes: 1

Views: 2647

Answers (1)

Yaniro
Yaniro

Reputation: 1587

In order access a single dimensional array with two dimensional coordinates, you have the following formula:

var pixel = pixels[ ( ( y * width ) + x ) * 4 ];

The * 4 was added to account for the r,g,b,a values. xResolution is the width if the image.

So source() would be:

function source( imageArray, x, y, imageWidth )
{
    var pos = ( ( y * imageWidth ) + x ) * 4;
    var val =
    {
        r : imageArray[ pos ],
        g : imageArray[ pos + 1 ],
        b : imageArray[ pos + 2 ],
        a : imageArray[ pos + 3 ]
    };

    return val;
}

Upvotes: 1

Related Questions