问题描述:

Currently I am working on making a Chroma Key HTML5 Camera test app.

http://jsfiddle.net/XuScp/

Currently it kind of works (It will select green in your background and remove it like any other Chroma Key, currently I took out the green color and replaced it with a kind of grey color as thats the background I currently have).

The issue I am having is drawing the background in the same canvas as the camera is in. Currently it draws to the canvas but once the camera is loaded the image disappears which I am guessing is being replaced by the camera.

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;

}

}

网友答案:

As far as I can tell, you only draw the background (this.ctxOutput.drawImage(bckg,0,0);) once, and that is during the doLoad function. Your loop does draw the altered video to the ctxOutput seemingly correctly, it just doesn't redraw the background upon the next loop. That COULD be the reason.

ALSO,

I would, instead of drawing the background for each loop, simply place the image behind the main canvas, using either an Image or Canvas element. You are already making the green pixels transparent, so you should be able to see everything through the main canvas. I might start with setting the z-index of each, and maybe setting their style.positions to 'absolute' to ensure one is exactly behind the other.

This will take away any lag that would have resulted from drawing the background image to the same canvas each loop.

I've come across multiple tutorials and benchmark tests that suggest layering with canvases. The background is usually static, so why constantly update it. Just make it its own canvas. Layer one on top of the other, each containing certain types of elements (static, uniform motion, independent motion, etc.) to ensure maximum performance.

I hope this was of some help!

Sincerely,

TheCrzyMan

网友答案:

@shayward - I agree with @TheCrzyMan, use hidden and display canvas tags to chromakey

I am sure you have seen this mozilla tut on chroma key.

Jeffrey Burtoft also has a step-by-step tut on this too.

Hope this helps.

相关阅读:
Top