Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/473.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用Web Workers使用本机画布函数进行绘图_Javascript_Html5 Canvas_Web Worker_Drawimage - Fatal编程技术网

Javascript 使用Web Workers使用本机画布函数进行绘图

Javascript 使用Web Workers使用本机画布函数进行绘图,javascript,html5-canvas,web-worker,drawimage,Javascript,Html5 Canvas,Web Worker,Drawimage,可以将通过getImageData获得的CanvasPixelArray发送到辅助脚本,让辅助脚本操作其背景线程中的像素,并最终将操作后的像素数组发布回 但是,我使用的是本机画布绘图功能,如drawImage。drawImage调用当前正在阻止UI线程。这会导致重新绘制按钮的速度变慢,并且在单击按钮时会出现明显的延迟,仅举几个缺点。(编辑:现在可以使用ctx.imageSmoothingEnabled=false,至少在带有WebKit前缀的WebKit上实现一个小的改进。) 我想使用WebWo

可以将通过
getImageData
获得的
CanvasPixelArray
发送到辅助脚本,让辅助脚本操作其背景线程中的像素,并最终将操作后的像素数组发布回

但是,我使用的是本机画布绘图功能,如
drawImage
drawImage
调用当前正在阻止UI线程。这会导致重新绘制按钮的速度变慢,并且在单击按钮时会出现明显的延迟,仅举几个缺点。(编辑:现在可以使用
ctx.imageSmoothingEnabled=false
,至少在带有
WebKit
前缀的WebKit上实现一个小的改进。)

我想使用WebWorkers将图形从主线程移动到背景线程。但是,我似乎无法将画布或上下文发送给工作人员

我确实发现:

注意:通常情况下,包括辅助线程在内的后台线程无法操作DOM。如果后台线程所采取的操作需要对DOM进行更改,那么他们应该将消息发回其创建者以完成该工作

但我想让DOM保持原样;我只想在画布元素上绘制东西。这是可能的,还是网络工作者真的只允许计算而不允许画画

(或者可以使用
drawImage
等功能来操作
CanvasPixelArray
而不是在画布上绘制?

[社区编辑:这个答案是2011年编写并接受的。其他技术已经出现(或正在出现)这可能使Web Workers和Canvas更好地共存;读者应了解本页上除此答案外的所有答案。]


不能将画布对象或画布上下文传递给工作线程,因为画布是DOM的一部分。

[5年后编辑:其中一些已经开始改变,新的web平台功能实际上允许从工作人员渲染到画布!有关更多信息,请参阅本博客:-其余答案提供给2011年时代的信息;)]

Web workers只能计算,不能修改DOM,也不能进行任何调用以绘制画布。但是,正如您所说,您可以将像素数组发布到Web worker以在那里进行处理并将其发回。由于这是异步的,我不明白为什么这会导致UI线程的任何减速,除非您故意阻止,直到Web worker响应s(你不应该这样)

因此,
drawImage
调用花费的时间太长,影响了用户界面,这似乎很奇怪。现在大多数画布都是硬件加速的,所以它们应该可以很好地跳过。我猜你是通过网络工作者在每帧绘制画布像素数组,这实际上意味着你是在用javascript软件渲染画布。JavaScript的速度太慢了,即使C++软件渲染器也有点慢,这就是硬件加速的重要性所在。因此,你可以在Web工作者中把某个东西渲染到画布像素数组中,然后当你得到结果缓存时,它就进入了一个代码>图像/代码>,然后将那个<代码>图像<代码>绘制成画布。随便你。那应该还是很快的


编辑:您可能想查看WebGL,在那里您可以编写片段着色器,这些着色器实际上是处理像素效果的小程序。它们完全在图形卡上运行,因此速度非常快。

您可以将
图像数据
发布到Web Worker,Web Worker将处理后的
图像数据
发送回调用者(主UI)线程

例如:

  • 创建Web工作程序:

    this.renderer = new Worker("renderer.js"); var ctx = this.canvas.getContext('2d'); var imageData = ctx.createImageData(width, height); this.renderer.postMessage({ image: imageData });
  • 在Web Worker中执行
    ImageData
    操作并将其发回主线程:

  • onmessage = function(e) { var processedImage = self.doImageProcessing(e.data.image); postMessage({ image: processedImage }); };
    有一个新的API来实现这一点(目前只有在启用pref的情况下Firefox才支持)

    看到和
    .

    那太遗憾了。那么这是正确的吗?我基本上是被迫使用主线程进行绘制的?确实没有办法绘制到
    CanvasPixelArray
    ?是的。即使你有一个与
    drawImage()相当的API
    CanvasPixelArray
    上运行时,您仍然需要将数据发布回UI线程以进行实际绘制。我听说过在这些情况下使用屏幕外画布,但这需要等待浏览器供应商来实现。如果有人在纯javascr中实现Canvas API,那不是很棒吗ipt以便我们可以在web worker中使用它。您可以将
    JSON.stringify
    CanvasPixelArray,在worker中对其进行操作,当您返回结果时,解析JSON,并使用
    putImageData
    将结果放在Canvast上。有一个新的API可以做到这一点(只有在启用pref的Firefox中才支持).请参阅和。事实上,我还没有实现Web Workers,这就是它当前被阻止的原因。WebGL看起来很有趣;它看起来像一个处理和绘图的全新世界。感谢您的建议。(由于某种原因,在我的Chrome电脑上,硬件加速比软件渲染慢得多,因此启用加速是不可能的(目前))。现在如果有人能够创建一个
    CanvasRenderingContext2D
    来操作web上的
    imageData
    worker@hvdd,您是否使用
    [imageData]进行了尝试
    postMessage
    ?@Pacerier的第二个参数中,我试图在chrome v79中传输
    ImageData
    ,结果是:“TypeError:未能在'Worker'上执行'postMessage':索引0处的值没有可转移类型。”解决方案是传递
    ImageData
    Worker.postMessage]的底层缓冲区(imageData.data.buffer,[imageData.data.buffer])
    这应该是Osi答案的更快版本吗?还是性能类似?是的,应该更快。 this.renderer.onmessage = function (e) { var ctx = this.canvas.getContext('2d'); ctx.putImageData(e.data.image, 0, 0); }