You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用JavaScript正确裁剪视频流捕获的画面(提取人脸区域)

问题:如何从视频捕获的画面中裁剪出中间的人脸区域

我参考MDN教程实现了用JavaScript从视频中捕获画面,当前代码可获取全屏画面,但需要裁剪出屏幕中间的人脸区域,修改drawImage参数后仅实现图片缩小,复制到其他画布也显示为空,求正确裁剪方法。

现有代码

HTML代码

<canvas id="canvas" style="display:none" ></canvas>
<div class="output">
  <img id="photo" alt="" src="">
</div>

JS代码

let imgElement = document.querySelector("#photo");
function takePicture(results) {
      let canvas = document.getElementById('canvas');
      let context = canvas.getContext('2d');

      if (width && height) {
          canvas.width = width;
          canvas.height = height;
          context.drawImage(results.image, 0, 0, canvas.width, canvas.height);

          let data = canvas.toDataURL('image/png');
          imgElement.setAttribute('src', data);
      } else {
        clearPhoto();
      }
  }

尝试过的修改

context.drawImage(results.image, 0, 0, canvas.width, canvas.height, 100, 100, 300, 300);

解决方案

你用错了drawImage的参数顺序,裁剪需要正确区分源图像的裁剪区域和目标画布的绘制区域:

drawImage的完整参数定义是:

context.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
  • sx/sy:源图像上要裁剪区域的左上角坐标
  • sWidth/sHeight:源图像上裁剪区域的宽高
  • dx/dy:目标画布上放置裁剪后图像的左上角坐标
  • dWidth/dHeight:目标画布上图像的显示宽高

要裁剪画面中间的人脸区域,按以下步骤修改即可:

  1. 计算源图像中间区域的坐标
    假设你要裁剪的人脸区域宽高为300x300,那么源图像的起始坐标需要取画面正中间:

    const faceWidth = 300;
    const faceHeight = 300;
    const sx = (width - faceWidth) / 2;
    const sy = (height - faceHeight) / 2;
    
  2. 调整画布尺寸(可选但关键)
    如果希望最终输出的是裁剪后的小图,必须把画布的实际宽高设为裁剪区域的大小(CSS设置的只是显示尺寸,不影响绘图区域):

    canvas.width = faceWidth;
    canvas.height = faceHeight;
    
  3. 正确调用drawImage
    把裁剪的源区域绘制到目标画布的左上角:

    context.drawImage(results.image, sx, sy, faceWidth, faceHeight, 0, 0, faceWidth, faceHeight);
    

修改后的完整函数

let imgElement = document.querySelector("#photo");
function takePicture(results) {
  let canvas = document.getElementById('canvas');
  let context = canvas.getContext('2d');

  if (width && height) {
    // 定义人脸裁剪区域的宽高
    const faceWidth = 300;
    const faceHeight = 300;
    // 计算源图像中间区域的起始坐标
    const sx = (width - faceWidth) / 2;
    const sy = (height - faceHeight) / 2;

    // 设置画布为裁剪后的实际尺寸
    canvas.width = faceWidth;
    canvas.height = faceHeight;

    // 裁剪并绘制到画布
    context.drawImage(results.image, sx, sy, faceWidth, faceHeight, 0, 0, faceWidth, faceHeight);

    let data = canvas.toDataURL('image/png');
    imgElement.setAttribute('src', data);
  } else {
    clearPhoto();
  }
}

之前复制到其他画布为空,大概率是因为画布实际尺寸未正确设置,或者drawImage参数顺序错误导致没有绘制有效内容。只要按上述方式调整,就能正确裁剪出中间的人脸区域。


内容的提问来源于stack exchange,提问作者Azamat Uzbekov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 09:50:15