Вы можете вытащить некоторые общие выражения:
for (var i = 0; i < w; i++) {
for (var j = 0; j < h; j++) {
var t = 4*w*j+4*i;
var dt = 4*j;
for (var k = 0; k < 4; k++) {
var total = 0, values = 0, temp = 0;
if (!(i == 0 && j == 0)) {
temp = data.data[t-dt-4+k];
if (temp !== undefined) values++, total += temp;
}
if (!(i == w - 1 && j == 0)) {
temp = data.data[t-dt+4+k];
if (temp !== undefined) values++, total += temp;
}
if (!(i == 0 && j == h - 1)) {
temp = data.data[t+dt-4+k];
if (temp !== undefined) values++, total += temp;
}
if (!(i == w - 1 && j == h - 1)) {
temp = data.data[t+dt+4+k];
if (temp !== undefined) values++, total += temp;
}
if (!(j == 0)) {
temp = data.data[t-dt+k];
if (temp !== undefined) values++, total += temp;
}
if (!(j == h - 1)) {
temp = data.data[t+dt+k];
if (temp !== undefined) values++, total += temp;
}
if (!(i == 0)) {
temp = data.data[t-4+k];
if (temp !== undefined) values++, total += temp;
}
if (!(i == w - 1)) {
temp = data.data[t+4+k];
if (temp !== undefined) values++, total += temp;
}
values++, total += data.data[t+k];
total /= values;
data.data[t+k] = total;
}
}
}
Вы можете попробовать переместить цикл на k
так, чтобы он находился снаружи, а затем сложить +k
в определение t
, сохранив немного более повторные вычисления. (Это может оказаться плохо по причинам локальности памяти.)
Вы можете попробовать переместить цикл на j
, чтобы выйти за пределы цикла на i
, что обеспечит вам лучшую локальность памяти. Это будет иметь большее значение для больших изображений; это может не иметь никакого значения для размера, который вы используете.
Довольно болезненно, но, возможно, очень эффективно: вы можете потерять множество условных операций, разбив свои циклы на {0,1..w-2, w-1} и {0,1..h-2, h- 1}.
Вы можете избавиться от всех этих undefined
тестов. Они действительно вам нужны, учитывая, что вы делаете все эти проверки диапазона?
Еще один способ избежать проверки диапазона: вы можете дополнить свое изображение (нулями) одним пикселем вдоль каждого края. Обратите внимание, что очевидный способ сделать это даст отличные результаты от вашего существующего кода по краям; это может быть хорошо или плохо. Если это плохо, вы можете определить соответствующее значение для деления.