我在尝试做一些动态的视觉效果,使用HTML5帆布'素的操纵,但我跑进一个问题,在那里设置的像素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);

分析与铬显示,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.

  1. 是这个猜测是否正确?
  2. 反正是有降低花费的时间设置的价值在CanvasPixelArray?
有帮助吗?

解决方案

试试缓存的一个参照 data 像素阵列。你的放慢可能是由于额外的财产的访问 imageData.data.看看 这篇文章 为更多的解释。

E.g。这应该可以更快,你怎么当前拥有的。

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);

其他提示

我不知道,如果这可以帮助你,因为你想操纵素,但对我来说,在火狐3.6.8,只是呼吁putImageData是非常、非常缓慢的,没有做任何像素的操纵。在我的情况下,我只想要恢复以前版本的图像已被保存与则getimagedata.太缓慢。

相反,我得到了它的工作以及使用toDataUrl/drawImage代替。对我来说这是工作速度不够快,我可以叫它在处理鼠标移活动:

保存:

savedImage = new Image()  
savedImage.src = canvas.toDataURL("image/png")

到恢复:

ctx = canvas.getContext('2d')  
ctx.drawImage(savedImage,0,0)

看起来像你在做一些种"复制",所以也许 drawImage 或者一次 putImageData 可能会有帮助。循环四分之一百万次到复制素单独地、而不是使用大规模的"复制"运作,倾向于将慢得多--而不仅仅是在Javascript;-).

奇怪的是,循环2d目列更快的比1d阵列计算部分抵消并没有对象。格式,因此,看看是否有帮助(在我的测试,它是20倍的速度更快).

(抬起头:这个脚本可能会崩溃你的浏览器!如果你碰它,稳坐几分钟的时间,并让它做的事情) http://jsfiddle.net/hc52jx04/16/

function arrangeImageData (target) {

var imageCapture = target.context.getImageData(0, 0, target.width, target.height);
var imageData = {
    data: []
};
imageData.data[0] = [];
var x = 0;
var y = 0;
var imageLimit = imageCapture.data.length;

for (var index = 0; index < imageLimit; index += 4) {

    if (x == target.width) {
        y++;
        imageData.data[y] = [];
        x = 0;
    }

    imageData.data[y][x] = {
        red: imageCapture.data[index],
        green: imageCapture.data[index + 1],
        blue: imageCapture.data[index + 2],
        alpha: imageCapture.data[index + 3]
    };
    x++;
}
return imageData;

}


function codifyImageData (target, data) {

var imageData = data.data;

var index = 0;
var codedImage = target.context.createImageData(target.width, target.height);

for (var y = 0; y < target.height; y++) {

    for (var x = 0; x < target.width; x++) {

        codedImage.data[index] = imageData[y][x].red;
        index++;
        codedImage.data[index] = imageData[y][x].green;
        index++;
        codedImage.data[index] = imageData[y][x].blue;
        index++;
        codedImage.data[index] = imageData[y][x].alpha;
        index++;
    }

}

return codedImage;

}

更多信息: http://discourse.wicg.io/t/why-a-straight-array-for-canvas-getimagedata/1020/6

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top