【问题标题】:Efficient pixel manipulation using javascript Canvas使用 javascript Canvas 进行有效的像素操作
【发布时间】:2014-01-31 15:33:39
【问题描述】:

我正在尝试在 JavaScript 中使用每个频道的网络摄像头延迟,而我当前的代码运行速度有点慢。可以看demohere

我的延迟方法是创建一个包含 12 个元素的数组来存储像素(画布元素),然后通过复制像素(使用 getImageData 和 putImageData 调用)将内容从一帧转移到另一帧。由于我正在拆分颜色通道,因此我的更新函数如下所示:

function update() {
    if (localMediaStream) {
        // Update history
        for (var i = hs - 1; i > 0; i--) {
            var ctxCurr = history[i].getContext('2d');
            var ctxPrev = history[i - 1].getContext('2d');
            try {
                ctxCurr.putImageData(ctxPrev.getImageData(0, 0, w, h), 0, 0);
            } catch (err) {
                console.log(err);
            }
        }
        // Write the most recent webcam frame
        var ctx0 = history[0].getContext('2d');
        ctx0.drawImage(video, 0, 0, w, h);
        // Get pixel data for most recent,halfway and last frames in history
        var r = history[0].getContext('2d').getImageData(0, 0, w, h).data;
        var g = history[hs / 2].getContext('2d').getImageData(0, 0, w, h).data;
        var b = history[hs - 1].getContext('2d').getImageData(0, 0, w, h).data;
        // Get a frame and it's pixels
        var imageData = ctx0.getImageData(0, 0, w, h);
        var data = imageData.data;
        // Write the r,g,b channels using the offset frames for green and blue channels
        for (var i = 0; i < data.length; i += 4) {
            data[i] = r[i];
            data[i + 1] = g[i + 1];
            data[i + 2] = b[i + 2];
        }

        rgb.putImageData(imageData, 0, 0);
    }
}

我想我可以跳过使用红色通道,因为最近的帧已经包含该信息。是否有更快的方法来操作/写入像素数据(getImageData()putImageData() 除外)或更快的方法来实现我想要实现的目标?

【问题讨论】:

    标签: javascript html canvas getusermedia


    【解决方案1】:

    看起来有几种方法可以加快您尝试执行的操作。 getImageData 非常慢,而 putImageData 慢得令人沮丧,因此消除这些调用将始终为您服务。忘记红色通道是对的。我也想去掉这条线:

    var r = history[0].getContext('2d').getImageData(0, 0, w, h).data;
    

    此外,您应该能够将画布绘制到适当的上下文中,只要您清除上下文即可。我相信你的 try 语句应该是这样的:

    try {
        ctxCurr.clearRect(0, 0, w, h);
        ctxCurr.drawImage(history[i-1], 0, 0);
    }
    

    删除所有对 putImageData 的冗余调用应该会有很大帮助。

    【讨论】:

    • 谢谢扎克! drawImage 比 putImageData/getImageData 有很大的提升
    • 我已经更新了代码,即使在我的 android 上它也能以不错的速度运行。再次感谢!
    【解决方案2】:

    要手动编码,我认为 put 和 getImageData 是通过画布完成的唯一方法。你可以使用一个 javascript 库。也许你可以操纵源头。我尝试了演示,它似乎比你的更流畅(尽管我喜欢你的幻彩色彩效果)。你可以找到图书馆here

    【讨论】:

    • “迷幻色彩效果”让它变慢了,因为我每秒复制 12 张 320x240 图像的像素(大约每秒 11059200 像素)。我快速浏览了您链接到的库,但它似乎使用了闪存后备。我猜我的问题是关于手写代码的javascript。我已经用actionscript进行了测试
    猜你喜欢
    • 2013-09-08
    • 2012-11-13
    • 1970-01-01
    • 2012-01-23
    • 2011-12-09
    • 2014-12-18
    • 2015-05-09
    • 2012-04-15
    • 1970-01-01
    相关资源
    最近更新 更多