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

使用CanvasRenderingContext2D.drawImage生成图像变形问题求助

修复Canvas drawImage截图变形与范围错误的问题

核心问题:drawImage参数误用

你的代码对drawImage的参数理解有误,该方法的第三、第四个参数是源图像的截取宽度/高度,而非截取区域的右下角坐标。你当前写的sx + 350和sy + 130会导致截取的源区域尺寸远大于预期(宽度495px、高度305px),这不仅会把遮罩外的内容包含进来,还会因为强制拉伸到350×130导致图像变形。

修复后的代码

直接将源截取宽度/高度设为目标尺寸350和130即可:

const sx = (640 - 350) / 2;
const sy = (480 - 130) / 2;
context.drawImage(
  this.$refs.video,
  sx,
  sy,
  350,  // 源截取宽度:对应遮罩的宽度
  130,  // 源截取高度:对应遮罩的高度
  0,
  0,
  350,
  130
);

调试步骤(确保完全匹配遮罩)

  1. 确认摄像头真实分辨率
    标称的640×480不一定是video元素的实际分辨率,打印以下值验证:

    console.log(this.$refs.video.videoWidth, this.$refs.video.videoHeight);
    

    用真实的videoWidth和videoHeight重新计算sx和sy,避免因尺寸不匹配导致偏移。

  2. 可视化截取范围
    在video上层添加一个临时canvas,画出你计算的截取矩形,对比遮罩位置是否完全重合:

    // 临时调试代码,执行后会在video上显示红色截取框
    const debugCanvas = document.createElement('canvas');
    debugCanvas.style.position = 'absolute';
    debugCanvas.style.top = this.$refs.video.offsetTop + 'px';
    debugCanvas.style.left = this.$refs.video.offsetLeft + 'px';
    debugCanvas.width = this.$refs.video.videoWidth;
    debugCanvas.height = this.$refs.video.videoHeight;
    const debugCtx = debugCanvas.getContext('2d');
    debugCtx.strokeStyle = 'red';
    debugCtx.lineWidth = 2;
    debugCtx.strokeRect(sx, sy, 350, 130);
    document.body.appendChild(debugCanvas);
    
  3. 检查Canvas绘图分辨率
    确保你的canvas元素的width和height属性设置为350×130,而非仅通过CSS样式设置显示尺寸——CSS控制的是显示大小,属性才是实际绘图的像素分辨率,不匹配会导致拉伸变形。

内容的提问来源于stack exchange,提问作者Bruno Lamps

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 02:52:24