Ошибки в обработке пикселей на холсте в Opera - PullRequest
2 голосов
/ 23 сентября 2011

Я изучаю HTML5 и при выполнении некоторых базовых вещей, таких как манипуляции с пикселями холста, обнаружил, что Opera полностью портит изображение, когда я хочу изменить цветовой канал.Я приготовил небольшую тестовую страницу, которая должна говорить сама за себя: http://gda.0fees.net/tests/opera/canvas2.html (Примечание: изображения «ожидаемого результата» загружаются динамически, а сервер работает медленно).

Сценарийберет изображение и изменяет значение красного цвета для каждого пикселя равномерным образом.Вот центральный пункт моего кода (который вы можете увидеть в полном объеме по ссылке выше):

for (var i = 0, l = matrix.data.length; i < l; i += 4)
{
    matrix.data[i] += delta;
    if (matrix.data[i] > 255) matrix.data[i] = 255;
    if (matrix.data[i] < 0  ) matrix.data[i] = 0;
}

В Chrome, Firefox, IE 9 и Safari он работает как шарм.В Opera, однако, я получаю этот результат для обоих преобразований: http://gda.0fees.net/tests/opera/opera.jpg

Я что-то не так делаю?Это известная ошибка?Можно ли это подавить?

1 Ответ

3 голосов
/ 23 сентября 2011

Если бы мне пришлось угадывать, я бы сказал, что значение красного канала было округлено до некоторого недопустимого значения.Обратите внимание (на исходном изображении), что все области с ошибками в целом намного ярче, чем области, которые обрабатываются должным образом.

Возможно, он выполняет какую-то проверку предела, обнуляя красное значение пикселей в местах, гдеИсходное значение красного цвета + 128 превысит максимальное значение, используемое для представления компонентов цвета (возможно, с использованием uint 8).

Я никогда раньше не использовал холст HTML5, но если вы сможете сэмплировать цвет каждого пикселя, выможет быть в состоянии подавить его, угадав максимальное значение и проверив, чтобы вы не превышали его при увеличении цветового компонента этого конкретного пикселя.

Попробуйте это:

// Apologies, my JavaScript is very rusty, and this isn't how I would do this.
for (var i = 0, l = matrix.data.length; i < l; i += 4)
{
    var current_red = matrix.data[i];
    var new_red = 0;

    if((current_red + delta) > 255) new_red = 255;
    else if((current_red - delta) < 0) new_red = 0;
    else new_red = current_red + delta;
}

// What I would do is this:
for (var i = 0, l = matrix.data.length; i< l; i+=4)
{
    // I don't know if JS has a clamp function :D
    matrix.data[i] = clamp(matrix.data[i] + delta, 0, 255);
}
...