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

Canvas绘制Video画面出现放大问题求助(附代码)

解决Canvas绘制Video画面放大的问题

嘿,我明白你遇到的这个困扰啦——把视频原封不动画到Canvas里,结果画面却被放大变形了,其实问题出在Canvas的两个关键尺寸没同步上!

问题根源:Canvas的两个尺寸要分清

Canvas有两个完全不同的尺寸属性:

  • CSS显示尺寸:通过canvas.style.width和canvas.style.height设置,控制Canvas元素在页面上的显示大小。
  • 实际画布分辨率:通过canvas.width和canvas.height属性设置,这是Canvas内部绘图区域的像素数量,决定了绘图的清晰度和比例。

你的代码里只设置了CSS显示尺寸,但没给Canvas的实际分辨率赋值,所以Canvas会使用默认的300x150像素尺寸,然后被CSS拉伸到视频的宽高,自然就会出现画面放大、变形的情况。

修复后的代码

只需要在设置CSS尺寸的同时,同步设置Canvas的width和height属性就行,另外把setTimeout换成requestAnimationFrame会让绘图更流畅(浏览器渲染帧同步,性能更好):

<canvas></canvas>
<video autoplay="true"></video>
<script>
let video = document.querySelector("video")
navigator.mediaDevices.getUserMedia({video: true})
  .then((stream) => {
    video.srcObject = stream
  })

let canvasWidth = 0
let canvasHeight= 0
video.addEventListener("playing", () => {
  canvasWidth = video.videoWidth
  canvasHeight = video.videoHeight
  const canvas = document.querySelector("canvas")
  
  // 关键修复:同时设置Canvas的实际分辨率和CSS显示尺寸
  canvas.width = canvasWidth
  canvas.height = canvasHeight
  canvas.style.width = `${canvasWidth}px`
  canvas.style.height = `${canvasHeight}px`

  function draw() {
    let ctx = canvas.getContext('2d');
    // 简化drawImage调用:直接按画布尺寸绘制即可
    ctx.drawImage(video, 0, 0, canvasWidth, canvasHeight)
    // 用requestAnimationFrame替代setTimeout,更流畅
    requestAnimationFrame(draw)
  }
  
  setTimeout(() =>{
    draw()
  }, 1000);
})
</script>

额外说明

  • 我简化了drawImage的参数,因为你要原封不动绘制视频,直接用ctx.drawImage(video, 0, 0, canvasWidth, canvasHeight)就足够了,不需要后面的目标区域参数(前后尺寸一致的话可以省略)。
  • requestAnimationFrame是浏览器专门为动画提供的API,会在每次屏幕刷新时调用,比setTimeout更高效,避免掉帧。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 13:37:43