【问题标题】:Extract snapshot from video element with camera source使用相机源从视频元素中提取快照
【发布时间】:2016-06-12 10:11:08
【问题描述】:

上下文

我正在尝试通过客户的摄像机捕捉快照并将其保存为图像。我有一个JSFiddle demo

问题

我无法使用 Context2D 的drawImage 将整个视频区域从视频元素转移到画布。虽然视频是 400 x 300

<video width="400" height="300" ...

并且画布是相同的 400 x 300

<canvas width="400" height="300" ...

当我绘制时,我为源和目标指定 400 x 300...

ctx.drawImage(video, 0, 0, 400, 300, 0, 0, 400, 300);

这是我的客户端发生的事情的示例。

红框元素是video,绿框元素是canvas

我怀疑这是因为视频流 不是 400 x 300(甚至不是 4:3 宽高比),但我还没有找到解决方案,或者至少在HTML 规范表明此行为是由视频流引起的。

有没有人在这方面有更多经验并且可以指出正确的方向?

抱歉,小提琴中的代码质量不好。

【问题讨论】:

    标签: javascript html video canvas


    【解决方案1】:

    当您设置 HTMLElement 的 widthheight 属性时,您只是设置了它的显示大小,而不是其中的框架大小。

    Canvas2dContext.drawImage(video, x, y) 将采用帧大小,(可以通过getUserMedia btw 强制设置)。

    因此,您需要将画布的宽度和高度设置为 video.videoWidthvideo.videoHeight 属性,以获得网络摄像头捕获的完整质量图像,而不是调用 ctx.drawImage(video, 0,0, 400, 300) 在画布上重新缩放它由 CSS 缩放,或在getUserMedia 调用期间直接设置强制(最新规格为navigator.mediaDevices.getUserMedia(video: { width: 300, height:300 });),但不幸的是,对于最新版本,您不能确定浏览器会遵守它,除非检查 video.videoHeight /宽度 ;-)

    var ctx = rendering.getContext('2d');
    
    btn.onclick = function() {
      switch (select.value) {
        case 'css rescale':
          rendering.width = 400;
          rendering.height = 300;
          ctx.drawImage(video, 0, 0, 400, 300);
          break;
        case 'full quality':
          rendering.width = video.videoWidth;
          rendering.height = video.videoHeight;
          ctx.drawImage(video, 0, 0);
          break;
      }
    }
    
    var initVideo = function(stream) {
      video.src = URL.createObjectURL(stream);
      video.play();
    };
    
    navigator.mediaDevices.getUserMedia({
        video: true
      })
      .then(function(s) {
        initVideo(s)
      })
      .catch(function(err) {
        if (err.message.indexOf('secure origins') > -1) {
          document.body.innerHTML = '<h3><a target="_blank" href="https://jsfiddle.net/x64ta5r3/">jsfiddle link for chrome and its https policy...</a></h3>(right click -> open Link...';
        }
      });
    <button id="btn">take a snapshot</button>
    <select id="select">
      <option value="css rescale">css rescale</option>
      <option value="full quality">full quality</option>
    </select>
    <video width="400" height="300" id="video"></video>
    <canvas id="rendering"></canvas>

    jsfiddle link for chrome and its https policy...

    【讨论】:

    • 感谢您的帮助!由于 Android 存在问题,我尚未接受答案。
    • 您能否更具体地谈谈这个问题?但基本上,如果你的 UA 没有设置 videoHeight 和 videoWidth 属性,你应该填一个 bug。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-08
    • 1970-01-01
    • 2013-03-10
    • 1970-01-01
    • 1970-01-01
    • 2014-12-03
    • 1970-01-01
    相关资源
    最近更新 更多