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

使用drawImage从Video元素绘图异常,分辨率错乱问题求助

解决Canvas drawImage绘制Video只显示小块/分辨率过低的问题

兄弟,我之前跟你一模一样,折腾这个问题快把头发薅秃了!一开始用this.canvasContext.drawImage(this.mainVideoElement, 0, 0),结果只显示视频左上角一小坨,后来试了drawImage各种参数组合,手动设宽高也没用,画出来的内容分辨率比视频低好几倍。后来才搞清楚是两个核心坑没踩对,给你捋捋解决方案:

1. 先区分Canvas的「真实绘图尺寸」和「CSS显示尺寸」

Canvas有两个完全独立的尺寸:

  • 一个是绘图缓冲区的实际像素尺寸(通过canvas.width/canvas.height控制),这才是决定绘制清晰度的关键;
  • 另一个是CSS里的显示尺寸,只是控制Canvas在页面上看起来多大,和绘图分辨率无关。

如果只给Canvas设了CSS尺寸,它的绘图缓冲区会默认用300x150的极小尺寸,这就导致你画视频的时候,只能显示左上角一小块,而且内容糊得离谱。

解决办法:
先获取视频的实际分辨率(注意是video.videoWidth和video.videoHeight,不是视频元素的CSS宽高!),然后把Canvas的绘图缓冲区尺寸设成和视频一致:

// 等视频加载完元数据再执行,不然videoWidth/videoHeight会是0
this.mainVideoElement.addEventListener('loadedmetadata', () => {
  this.canvas.width = this.mainVideoElement.videoWidth;
  this.canvas.height = this.mainVideoElement.videoHeight;
});

如果需要Canvas在页面上按特定大小显示,再单独设置CSS样式,比如:

canvas {
  width: 800px; /* 你想要的显示宽度 */
  height: auto; /* 保持视频比例不变形 */
}

2. 用drawImage的完整参数指定源和目标尺寸

直接用drawImage(video, 0, 0)的时候,Canvas会默认按视频元素的CSS尺寸来绘制,而不是视频的实际分辨率,这就会导致要么只显示一部分,要么拉伸模糊。正确的做法是指定完整的8个参数:

this.canvasContext.drawImage(
  this.mainVideoElement,
  0, 0, 
  this.mainVideoElement.videoWidth, this.mainVideoElement.videoHeight, // 源:取视频实际分辨率
  0, 0, 
  this.canvas.width, this.canvas.height // 目标:和Canvas绘图缓冲区尺寸匹配
);

这样就能保证视频的每一个像素都对应到Canvas的像素上,不会出现裁切或模糊。

3. 额外避坑提示

  • 一定要等视频触发loadedmetadata事件再执行绘制,不然videoWidth和videoHeight还没拿到正确值,设置的Canvas尺寸会是0;
  • 如果视频是动态切换源的,记得每次切换后重新获取视频分辨率并更新Canvas的width和height;
  • 要是你的Canvas需要响应窗口大小变化,记得在 resize 事件里重新调整CSS显示尺寸,但别改canvas.width/canvas.height(不然绘图分辨率会变)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 14:47:39