我正在制作一个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的值。就是这样。
由于这太慢了...有没有更好的方法,可以利用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
谢谢!
丹尼尔
globalCompositeOperation
以保留 alpha 值)。 - Phrogz