Я пытаюсь сделать некоторые динамические визуальные эффекты с помощью пиксельного управления холста HTML 5, но я сталкиваюсь с проблемой, где установка пикселей в CanvasPixelArray является смехотворно медленной.
Например, если у меня есть код как:
imageData = ctx.getImageData(0, 0, 500, 500);
for (var i = 0; i < imageData.length; i += 4){
imageData.data[i] = buffer[i];
imageData.data[i + 1] = buffer[i + 1];
imageData.data[i + 2] = buffer[i + 2];
}
ctx.putImageData(imageData, 0, 0);
Профилирование с Chrome показывает, это работает на 44% медленнее, чем следующий код, где CanvasPixelArray не используется.
tempArray = new Array(500 * 500 * 4);
imageData = ctx.getImageData(0, 0, 500, 500);
for (var i = 0; i < imageData.length; i += 4){
tempArray[i] = buffer[i];
tempArray[i + 1] = buffer[i + 1];
tempArray[i + 2] = buffer[i + 2];
}
ctx.putImageData(imageData, 0, 0);
Мое предположение - то, что причина этого замедления происходит из-за преобразования между JavaScript, удваивается и внутренние неподписанные целые числа на 8 битов, используемые CanvasPixelArray.
Попробуйте кэшировать ссылку на массив пикселей data
. Замедление может быть связано с дополнительным доступом к свойству imageData.data
. См. эту статью для получения дополнительных объяснений.
Например. Это должно быть быстрее, чем у вас сейчас.
var imageData = ctx.getImageData(0, 0, 500, 500),
data = imageData.data,
len = data.length;
for (var i = 0; i < len; i += 4){
data[i] = buffer[i];
data[i + 1] = buffer[i + 1];
data[i + 2] = buffer[i + 2];
}
ctx.putImageData(imageData, 0, 0);
Похоже, вы делаете что-то вроде "блиттинга", так что, возможно, drawImage или all-at-once putImageData могут помочь. Четверть миллиона циклов для копирования пикселей ind По отдельности, вместо того, чтобы использовать массовые операции «блиттинга», он, как правило, работает намного медленнее - и не только в Javascript ;-).