Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.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 worker问题在画布上进行位图过滤_Javascript_Video_Canvas - Fatal编程技术网

Javascript 使用web worker问题在画布上进行位图过滤

Javascript 使用web worker问题在画布上进行位图过滤,javascript,video,canvas,Javascript,Video,Canvas,我正在制作一个视频,将像素复制到画布上,并使用web worker应用实时位图过滤器 使用web worker时,我无法在画布上看到结果更改(应为黑白) 这是我的代码: 我可以通过使用中间画布来解决这个问题,但我真的不想这样做 我的代码大致基于这个示例,与我的代码相同,只是没有使用web worker进行图像过滤处理。 我的代码有什么问题 注意:需要一个支持WebWorker和HTML5视频/画布的现代浏览器,这是因为draw()不等待WebWorker的返回值,而是使用requestAni

我正在制作一个视频,将像素复制到画布上,并使用web worker应用实时位图过滤器

使用web worker时,我无法在画布上看到结果更改(应为黑白)

这是我的代码:

我可以通过使用中间画布来解决这个问题,但我真的不想这样做

我的代码大致基于这个示例,与我的代码相同,只是没有使用web worker进行图像过滤处理。

我的代码有什么问题


注意:需要一个支持WebWorker和HTML5视频/画布的现代浏览器,这是因为
draw()
不等待WebWorker的返回值,而是使用
requestAnimationFrame
。如果要连续过滤图像,必须在应用过滤器后调用
draw

filterWorker.addEventListener('message', function(e) {
    ctx.putImageData(e.data, 0, 0);
    requestAnimationFrame(draw);
}, false);
但是,如果过滤器需要很长时间,则
draw
很可能会在画布上填充彩色数据,以便尽早注意到更改(我能够在当前版本中看到带有FF17的黑白版本)

我的代码有什么问题

在操作顺序很重要的场景中,您使用的是并行计算工具:您希望在显示每个图像之前对其应用过滤器。让我:

关于线程安全 该接口产生了真正的操作系统级线程,如果您不小心,细心的程序员可能会担心并发会在代码中造成“有趣”的效果

然而,由于web工作人员小心地控制了与其他线程的通信点,因此实际上很难引起并发问题。无法访问非线程安全组件或DOM。您必须通过序列化对象将特定数据传入和传出线程。因此,您必须非常努力地工作,以便在代码中产生问题

与真正的OS级线程一样,除非使用某种阻塞机制,否则无法对执行顺序进行任何假设,但JavaScript中不包含这种机制。因此,您需要在同一线程中绘制和操作图像

进一步解释 序贯病例 请看下图:

这就是techdemo中的基本情况
draw()
复制视频并立即过滤图像:

function draw(v,c,w,h,filter) {
    if(v.paused || v.ended) return false;
    c.drawImage(v,0,0,w,h);
    if (typeof filter === 'undefined') {
        // variable is undefined
    } else {
        var idata = c.getImageData(0,0,w,h);
        newdata = filterdata(idata,filter);
        c.putImageData(newdata,0,0);
    }
    setTimeout(draw,20,v,c,w,h,filter);
}
正如您所看到的,
drawImage
的调用与以下过滤器之间没有间隙。结果图片显示约20毫秒。即使过滤器需要1毫秒,用户也可能不会注意到这一点

平行箱 现在它变得有点复杂了。黑色文本框是直接修改画布的方法,白色框表示触发的事件或注册的超时,黑色框表示超时的执行或事件的处理:

现在,发生了什么<代码>绘制仍然大约每隔20毫秒调用一次,并复制视频。然后,它向工作者发布一条消息。但是,没有说明何时发送此消息。它可以立即放在worker的事件循环中(如图所示),或者放在“main”的事件循环中,稍后再调度(更可能)

与顺序法相比,这个过程需要非常非常长的时间。请记住,您还需要将处理后的数据发送回,
filter
filterWorker
的事件侦听器可能会在比您最初预期的时间晚的时候触发。但是,即使您实际处理并显示数据,下面对
draw
的调用也会毁掉您所有的辛苦工作

解决方案
不要使用web worker,或者使用隐藏画布作为worker的源。

发生这种情况是因为
draw()
不等待WebWorker的返回值,而是使用
requestAnimationFrame
。如果要连续过滤图像,必须在应用过滤器后调用
draw

filterWorker.addEventListener('message', function(e) {
    ctx.putImageData(e.data, 0, 0);
    requestAnimationFrame(draw);
}, false);
但是,如果过滤器需要很长时间,则
draw
很可能会在画布上填充彩色数据,以便尽早注意到更改(我能够在当前版本中看到带有FF17的黑白版本)

我的代码有什么问题

在操作顺序很重要的场景中,您使用的是并行计算工具:您希望在显示每个图像之前对其应用过滤器。让我:

关于线程安全 该接口产生了真正的操作系统级线程,如果您不小心,细心的程序员可能会担心并发会在代码中造成“有趣”的效果

然而,由于web工作人员小心地控制了与其他线程的通信点,因此实际上很难引起并发问题。无法访问非线程安全组件或DOM。您必须通过序列化对象将特定数据传入和传出线程。因此,您必须非常努力地工作,以便在代码中产生问题

与真正的OS级线程一样,除非使用某种阻塞机制,否则无法对执行顺序进行任何假设,但JavaScript中不包含这种机制。因此,您需要在同一线程中绘制和操作图像

进一步解释 序贯病例 请看下图:

这就是techdemo中的基本情况
draw()
复制视频并立即过滤图像:

function draw(v,c,w,h,filter) {
    if(v.paused || v.ended) return false;
    c.drawImage(v,0,0,w,h);
    if (typeof filter === 'undefined') {
        // variable is undefined
    } else {
        var idata = c.getImageData(0,0,w,h);
        newdata = filterdata(idata,filter);
        c.putImageData(newdata,0,0);
    }
    setTimeout(draw,20,v,c,w,h,filter);
}
正如您所看到的,
drawImage
的调用与以下过滤器之间没有间隙。结果图片显示约20毫秒。即使过滤器需要1毫秒,用户也可能不会注意到这一点

平行箱 现在它变得有点复杂了。黑色文本框是直接修改画布的方法,白色框表示触发的事件或注册的超时,以及