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
相关产品推荐
相关产品推荐

