【问题标题】:Rendering video element to canvas - unwanted stretching?将视频元素渲染到画布 - 不需要的拉伸?
【发布时间】:2016-06-30 10:15:23
【问题描述】:

我正在尝试生成视频的屏幕截图。目标是生成与视频第一帧相同的图像。但是,我遇到了结果图像被拉伸的问题。

此图像在左侧显示视频,在一开始就暂停 - 以及在右侧生成的图像:

注意到底部的灰色区域了吗?它已被拉伸到比视频更高的高度。

我正在使用以下代码生成屏幕截图:

示例标记:

<video id="video" height="300" width="320" preload="auto">
    <source src="http://domain.com/video.mp4">
</video>
<canvas id="canvas" height="300" width="320"></canvas>

脚本:

// Grab an existing video element, 300px tall, 320px wide.
var video = document.getElementById('video');
// Grab existing canvas, 300px tall, 320px wide.
var canvas = document.getElementById('canvas');
// Wait until video has loaded
video.addEventListener('loadeddata', function() {
    var context = canvas.getContext('2d');
    // Render using same dimensions.
    context.drawImage(video, 0, 0, 320, 300);
}, false);

有人可以告诉我如何避免这种拉伸吗?

【问题讨论】:

  • canvas.style.widthcanvas.style.height 属性只是页面显示属性,与画布像素分辨率无关。您需要将canvas.widthcanvas.height 设置为正确的分辨率
  • 我直接在元素上设置宽度和高度。我已将用于创建示例屏幕截图的标记添加到问题示例代码中。
  • 不,您必须将其设置为媒体的宽度和高度,视频元素的尺寸属性也仅显示尺寸。可以通过js用video.videoWidthvideo.videoHeight检索。

标签: javascript html canvas


【解决方案1】:

就像&lt;img&gt; 元素,&lt;video&gt; 元素的widthheight 属性调整容器大小。另一方面,drawImagemethod 使用该内容。

然后您必须使用videoElement.videoWidthvideoElement.videoHeight 属性来检索媒体的宽度和高度(img.naturalWidthimg.naturalHeight 用于图像元素)。

所以你有两种可能性:

您想以真实大小拍摄视频:

var ctx = canvas.getContext('2d');
btn.onclick = function(){
  // set your canvas width and height to the media's ones
  canvas.width = vid.videoWidth;
  canvas.height = vid.videoHeight;
  ctx.drawImage(vid, 0,0);
  };
<video src="http://vjs.zencdn.net/v/oceans.mp4" width="200" height="100" autoplay controls muted loop id="vid"></video><button id="btn">take a screenshot</button>
<canvas id="canvas"></canvas>

或者如果你想截取你的视频元素,你会面临更多 复杂性,因为您必须伪造默认的object-fit: contain; CSS 属性。这要归功于ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight); 属性。

你可以找到一种方法here,还有一种更完整的方法here,所以我不会在这个答案中包含它,只要记住使用video.videoWidthvideo.videoHeight属性作为sourceWidth和sourceHeight。

【讨论】:

  • 您是否认为视频的自然大小与我设置的不一样?我没有调整视频的大小 - mp4 文件的帧宽度为 320 像素,帧高度为 300 像素。与您的示例一样,我只是尝试以自然大小截取视频的屏幕截图。然而,生成的屏幕截图似乎将其内容拉长了。
  • @Tyler 嗯,是的,鉴于您的解释,这就是我的想法。这是我能想到的唯一可能。你能检查一下你身边的video.videoHeight === 300吗?
  • 是的,video.videoHeight 显示为 300。我制作了一个基本版本的我正在尝试做的事情,以便您可以看到我正在使用的实际视频:jsfiddle.net/owLgg94b
  • 好的,我可以 reproduce it 但只能在 chrome 上... 和 only with your video。你可能会向 bugzilla 提出一个错误...,我会尝试找到更多时间来调查它。但是现在,我将给出这个一般性的答案,因为您似乎处于一个非常特殊的情况。
  • 您使用的是 Windows 吗?我今天早上刚刚再次测试了小提琴,错误出现在我的 PC 上,但没有出现在我的 Mac 上 - 使用完全相同版本的 Chrome。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多