通过网络摄像头在 canvas 上设置背景图片

setting background image on canvas from web camera

我的目标是设置来自网络摄像头的背景图像。每次我点击按钮,背景图片都会改变。我正在更新功能中从网络摄像头绘制图像。但是有问题。背景图像总是在变化。我必须在更新功能中绘制此图像。

window.onload = function() {

  backgroundImage = null;

  // Grab elements, create settings, etc.
  var video = document.getElementById('video');

  // Get access to the camera!
  if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
    // Not adding `{ audio: true }` since we only want video now
    navigator.mediaDevices.getUserMedia({
      video: true
    }).then(function(stream) {
      video.src = window.URL.createObjectURL(stream);
      video.play();
    });
  }

  //get canvas and context element
  var c = document.getElementById("canvas");
  var ctx = c.getContext("2d");

  // Trigger photo take
  document.getElementById("snap").addEventListener("click", function() {
    backgroundImage = video;
  });

  //call update function every 80 nanoseconds
  setInterval(function() {
    update(c, ctx);
  }, 80);
}


function update(c, ctx) {
  if (backgroundImage) {
    ctx.drawImage(backgroundImage, 0, 0, 640, 480);
  }
  ctx.rect(20, 20, 150, 100);
  ctx.stroke();
}
<video id="video" width="640" height="480" autoplay></video>
<button id="snap">Snap Photo</button>
<canvas id="canvas" width="640" height="480"></canvas>

您必须使用屏幕外 canvas 拍摄快照,然后将屏幕外 canvas 绘制在您可见的屏幕上。

//get canvas and context element
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
// create an offscreen canvas to take your snapshots
var snapper = c.cloneNode().getContext('2d');

window.onload = function() {

  // Grab elements, create settings, etc.
  var video = document.createElement('video');

  // Get access to the camera!
  if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
    // Not adding `{ audio: true }` since we only want video now
    navigator.mediaDevices.getUserMedia({
      video: true
    }).then(function(stream) {
      // don't use createObjectURL(stream), it's deprecated because it locks hardware
      video.srcObject = stream;
      video.play();
    })
    .catch(e =>{
      console.log('Please visit the https fiddle at https://jsfiddle.net/Kaiido/7uugy7td/');
      });
  }
  // Trigger photo take
  document.getElementById("snap").addEventListener("click", function() {
    // draw the video's current frame on the off-screen canvas
    snapper.drawImage(video, 0, 0);
  });
}


function update() {
  // draw our offscreen canvas on the visible one.
  ctx.drawImage(snapper.canvas, 0, 0, 640, 480);
  ctx.rect(20, 20, 150, 100);
  ctx.stroke();
  // don't use setInterval for animations
  requestAnimationFrame(update);
}
update();
<button id="snap">Snap Photo</button>
<canvas id="canvas" width="640" height="480"></canvas>

还有 fiddle chrome 的直播。