Заставить алгоритм размытия работать с данными изображения холста? - PullRequest
1 голос
/ 02 января 2012

У меня есть следующий простой алгоритм размытия:

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

И мне нужно сделать эту работу с массивом, сгенерированным canvas с помощью getImageData ().Проблема в том, что массив из canvas является одномерным, а алгоритму требуется двухмерный, потому что «kx» и «ky» - это расстояния от текущего пикселя, а в двумерном массиве вы просто меняете один из индексов вчтобы двигаться влево или вправо по сетке, но в одномерном массиве (который пытается представить двухмерный. один) вы не можете этого сделать.

Как вы думаете, как я долженподойти к этой проблеме?На мой взгляд, вся проблема здесь:

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

Эта строка должна получить правильные пиксели из одномерного массива, и она должна работать нормально.

PS Я забыл сказатьчто я пытаюсь размыть изображение по одному каналу за раз, например:

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

, и я передаю каждый массив (красный, зеленый и синий) индивидуально алгоритму.

1 Ответ

1 голос
/ 02 января 2012

Чтобы получить доступ к одномерному массиву с двухмерными координатами, у вас есть следующая формула:

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

* 4 было добавлено для учета значений r, g, b, a.xResolution - это ширина, если изображение.

Так source () будет:

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