将视频元素渲染到画布 - 不必要的拉伸?

时间:2016-06-29 18:38:49

标签: javascript html5 canvas

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

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

enter image description here

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

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

示例标记:

<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);

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

1 个答案:

答案 0 :(得分:0)

就像<img>元素一样,<video>元素的widthheight属性会调整容器的大小。另一方面,drawImage方法确实使用了内容。

然后,您必须使用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.videoWidth和{{1} } attribute为sourceWidth和sourceHeight。