3

我目前正在用 JavaScript 编写图像编辑程序。我选择 JS 是因为我想了解更多。我正在处理的平均图像大小约为 3000 x 4000 像素。当转换为 imageData(用于编辑像素)时,我必须处理多达 48000000 个值。这就是为什么我决定引入 webworkers 并让他们只编辑数组的第 n 部分。假设我有十个网络工作者,每个工作者将不得不处理 4800000 个值。为了能够使用网络工作者,我将大数组通过我选择的线程数量进行划分。我使用的代码如下所示:

while(pixelArray.length > 0){
    cD.pixelsSliced.push(pixelArray.splice(0, chunks)); //Chop off a chunk from the picture array
}

稍后工作人员对数组做了一些处理后,他们将其保存到另一个数组中。每个工人都有一个 ID,并将他的部分保存在提到的数组中他的 id 的位置(以确保数组保持正确的顺序)。我使用 $.map 将该数组(看起来像 [[1231][123213123][213123123]] 连接到一个大数组 [231231231413431] 中,稍后我将从中创建我需要的 imageData。它看起来像这样:

cD.newPixels = jQuery.map(pixelsnew, function(n){
    return n;
});

创建此数组(cD.pixelsSliced)后,我创建 imageData 并将此图像复制到 imageData-Object 中,如下所示:

cD.imageData = cD.context.createImageData(cD.width, cD.height);
for(var i = 0; i < cD.imageData.data.length; i +=4){ //Build imageData
    cD.imageData.data[i + eD.offset["r"]] = cD.newPixels[i + eD.offset["r"]];
    cD.imageData.data[i + eD.offset["g"]] = cD.newPixels[i + eD.offset["g"]];
    cD.imageData.data[i + eD.offset["b"]] = cD.newPixels[i + eD.offset["b"]];
    cD.imageData.data[i + eD.offset["a"]] = cD.newPixels[i + eD.offset["a"]];
}

现在我意识到我在这里处理大量数据,我可能不应该使用浏览器进行图像编辑,而是使用不同的语言(我在 uni 中使用 Java)。但是我想知道您是否对性能有任何提示,因为坦率地说,当我第一次尝试大图像时,我感到非常惊讶。我没有想到,加载图像需要“那么长”的时间(代码的第一次和平)。Firefox 实际上认为我的脚本已损坏。其他两部分代码是我发现会减慢脚本速度的部分(这是正常的)。所以是的,我会感谢任何提示。

谢谢

4

1 回答 1

2

我建议在使用 Web Workers 时研究可转移对象而不是结构化克隆。Web Worker 通常使用结构化克隆来传递对象,换句话说,就是制作一个副本。对于大型对象(例如大型图像),这可能会花费大量时间。

使用 Transferable Objects 时,数据会从一个上下文传输到另一个上下文。换句话说,零拷贝,应该会提高向 Worker 发送数据的性能。

欲了解更多信息检查: http ://www.w3.org/html/wg/drafts/html/master/infrastructure.html#transferable-objects

此外,另一个想法可能是将拆分和对接大型数组的任务转移到 web worker 上。只是在这里进行头脑风暴,但是,也许您可​​以先生成一个 Web Worker,我们称它为 Mother Worker。该工人可以拆分阵列,然后生成 10 个其他执行繁重任务的子工人并将其送回给他们的母亲。

母亲最终将所有内容重新组合在一起并发送回主应用程序。

于 2013-08-21T11:11:44.680 回答