使用canvas快速实现视频截图功能

3,333 阅读2分钟

原理分析

先使用canvas将要截图的范围绘制到canvas上,再将绘制了图像的canvas转为一个图片展示的data URI。

得到URI后就可以将截图展示出来了。

使用到的API
  1. canvas的drawImage()方法可以在canvas上绘制图像。语法为:

ctx.drawImage(imageOrigin, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);

其中,第一个参数imageOrigin表示图像的来源,可以是图像元素、video元素等等。 其他参数的含义分别为:

  • sx可选:以左上角为坐标原点,要截取的起点的横坐标。
  • sy可选:以左上角为坐标原点,要截取的起点的纵坐标。
  • sWidth可选:要截取的宽度。
  • sHeight可选:要截取的高度。
  • dx:以目标canvas左上角为坐标远点,要画到canvas上的起点的横坐标。
  • dy:以目标canvas左上角为坐标远点,要画到canvas上的起点的纵坐标。
  • dWidth可选:要绘制的图像的宽度,允许缩放,默认不缩放。
  • dHeight可选:要绘制的图像的高度,允许缩放,默认不缩放。

总结下来,前四个参数用来选定要截图的范围,后四个参数规定要绘制的范围。

  1. canvas的toDataURL()方法返回一个包含图片展示的data URI。语法为:

canvas.toDataURL(type, encoderOptions);

  • type可选:图片格式,默认为 image/png
  • encoderOptions可选:在指定图片格式为 image/jpeg 或 image/webp的情况下,可以从 0 到 1 的区间内选择图片的质量。如果超出取值范围,将会使用默认值 0.92。其他参数会被忽略。

代码实现

首先需要创建canvas,并指定其宽度和高度为目标截图的宽度和高度。

const imageSize = { width: 208, height: 158 };
const canvas = document.createElement('canvas');
canvas.width = imageSize.width;
canvas.height = imageSize.height;
const ctx = canvas.getContext('2d');

接着绘制canvas图像,选择一个需要截图的视频的video元素作为参数传入绘制方法。x和y表明了从视频的哪里开始截图。注意要将canvas的绘制起点放在原点,因此canvas的横纵坐标都填0。

ctx.drawImage(video, x, y, imageSize.width, imageSize.height, 0, 0, imageSize.width, imageSize.height);

最后一步,将绘制好的canvas转为图片,得到的结果可以直接用于图片展示。

const url = canvas.toDataURL();
img.src = url;

最后封装成一个截图函数,完整代码如下:

function getShot(video, x, y, width, height) {
  const canvas = document.createElement('canvas');
  canvas.width = width;
  canvas.height = height;
  const ctx = canvas.getContext('2d');
  
  ctx.drawImage(video, x, y, width, height, 0, 0, width, height);
  
  return canvas.toDataURL();
}

注意事项

toDataURL方法需要限制video同源,如果video跨域会报错。