将两个图像绘制到HTML5 Canvas

时间:2013-02-05 19:07:15

标签: javascript html5 canvas

目前我正在制作色度键HTML5相机测试应用。

http://jsfiddle.net/XuScp/

目前它有点工作(它将在你的背景中选择绿色并像任何其他色度键一样将其删除,目前我拿出绿色并用一种灰色替换它,就像我现在的背景一样)。

我遇到的问题是在相机所在的画布中绘制背景。目前它绘制到画布,但是一旦相机加载,图像就会消失,而我猜测它正在被相机取代。

var bckg;
    bckg = new Image();
    bckg.src = 'https://raw.github.com/haywars/greenscreen/master/cambackgrounds/background1.jpg';
    function getImage(url){
        bckg= new Image();
        bckg.src = url;
    };

var processes = {
    timerCallback: function() {
        if (this.myVideo.paused || this.myVideo.ended) {
            return;
        }
        this.ctxInput.drawImage(this.myVideo, 0, 0, this.width, this.height);
        this.pixelScan();
        var self = this;
        setTimeout(function () {
            self.timerCallback();
        }, 0);
    },


    doLoad: function() {
        var video = document.querySelector('video');
        var canvas = document.querySelector('canvas');
        var ctx = canvas.getContext('2d');
        this.myVideo = document.getElementById("myVideo");
        this.cInput = document.getElementById("cInput");
        this.ctxInput = this.cInput.getContext("2d");
        this.cOutput = document.getElementById("cOutput");
        this.ctxOutput = this.cOutput.getContext("2d");
        var self = this;
        this.ctxOutput.drawImage(bckg,0,0);
        this.myVideo.addEventListener("playing", function() {
            self.width = self.myVideo.videoWidth;
            self.height = self.myVideo.videoHeight;
            self.timerCallback();
        }, false);
    },
    pixelScan: function() {
        var frame = this.ctxInput.getImageData(0, 0, this.width, this.height);
        for (var i = 0; i < frame.data.length; i++) {
            var r = frame.data[i];
            var g = frame.data[i+1];
            var b = frame.data[i+2];
            if (g > 0 && r > 50   && r < 165 && b < 60)
            frame.data[i + 3] = 0;
        }
        this.ctxOutput.putImageData(frame, 0, 0);

        //var img= new Image();
        //img.src = "images/cambackgrounds/background1.jpg";
        //this.ctxOutput.putImageData(img, 0, 0);
        return;
    }

}

2 个答案:

答案 0 :(得分:0)

据我所知,你只画了一次背景(this.ctxOutput.drawImage(bckg,0,0);),那是在doLoad函数中。您的循环确实将已更改的视频绘制到ctxOutput看似正确,它只是在下一个循环时不重绘背景。这可能是原因。

此外,

我会使用Image或Canvas元素,而不是为每个循环绘制背景,只需将图像放在主画布后面。您已经使绿色像素透明,因此您应该能够通过主画布看到所有内容。我可以从设置每个的z-index开始,也可以将style.position设置为'absolute'以确保一个完全落后于另一个。

这将消除因将背景图像绘制到每个循环的相同画布而导致的任何延迟。

我遇到了多个教程和基准测试,建议用画布分层。背景通常是静态的,所以为什么要不断更新它。把它做成自己的画布。第一层在另一层之上,每层包含某些类型的元素(静态,均匀运动,独立运动等),以确保最佳性能。

我希望这有一些帮助!

此致

TheCrzyMan

答案 1 :(得分:0)

@shayward - 我同意@TheCrzyMan,使用隐藏和显示画布标签到chromakey

我相信你已经看到了mozilla tut on chroma key

Jeffrey Burtoft也有step-by-step tut

希望这有帮助。