Я играю в небольшую HTML5-игру и, загружая свои спрайты в начале карты, я выполняю некоторую обработку с помощью GetImageData () /, перебирая все изображение / PutImageData ().
Это потрясающе работает на моем ПК, однако на мобильных телефонах это ужасно медленно.
PC: 5-6 ms
iPhone 4: 300-600 ms
Android HTC Desire S: 2500-3000 ms
Я проводил ОЧЕНЬ базовый бенчмаркинг, и GetImageData, и PutImageData работают очень быстро, что занимает много времени, это циклический просмотр содержимого.
Теперь я , очевидно, ожидаю замедления на телефоне, но 1000х звучит немного чрезмерно, и загрузка на моем HTC занимает около 4 минут, так что это не сработает. Кроме того, все остальное в игре работает на очень разумной скорости (главным образом потому, что экран смехотворно меньше, но все же он работает на JS на мобильном телефоне на удивление хорошо)
То, что я делаю в этой обработке - это "затемнение" спрайта до определенного уровня. Я просто перебираю все пиксели и умножаю их на значение <1. Вот и все. </p>
Так как это слишком медленно ... Есть ли лучший способ сделать то же самое, используя функциональность Canvas (композитинг, прозрачность и т. Д.), Без циклического прохождения всех пикселей по одному?
ПРИМЕЧАНИЕ. Этот слой имеет около 100% прозрачных пикселей и около 100% непрозрачных пикселей. Оба должны оставаться либо на 100% непрозрачными, либо на 100% прозрачными.
Вещи, о которых я думал, не сработают:
1) Рисование спрайтов на новом холсте с меньшей непрозрачностью. Это не сработает, потому что мне нужно, чтобы спрайты оставались непрозрачными, только темнее.
2) Рисование спрайтов и рисование полупрозрачного черного прямоугольника поверх них. Это сделает их темнее, но мои прозрачные пиксели больше не будут прозрачными ...
Есть идеи?
Это код, который я использую, на случай, если вы увидите в нем что-то ужасно идиотское:
function DarkenCanvas(baseImage, ratio) {
var tmpCanvas = document.createElement("canvas");
tmpCanvas.width = baseImage.width;
tmpCanvas.height = baseImage.height;
var ctx = tmpCanvas.getContext("2d");
ctx.drawImage(baseImage, 0, 0);
var pixelData = ctx.getImageData(0, 0, tmpCanvas.width, tmpCanvas.height);
var length = pixelData.data.length;
for (var i = 0; i < length; i+= 4) {
pixelData.data[i] = pixelData.data[i] * ratio;
pixelData.data[i + 1] = pixelData.data[i + 1] * ratio;
pixelData.data[i + 2] = pixelData.data[i + 2] * ratio;
}
ctx.putImageData(pixelData, 0, 0);
return tmpCanvas
}
РЕДАКТИРОВАТЬ: Это пример того, что я пытаюсь сделать с изображением:
Оригинал: http://www.crystalgears.com/isoengine/sprites-ground.png
Потемнело: http://www.crystalgears.com/isoengine/sprites-ground_darkened.png
Спасибо!
Daniel