目标,截取红色色块背后的视频区域。
代码结构如下:
<div id="p1"><video id="v1" autoplay playsinline></video><div id="mrz"></div><canvas id="captureCanvas"></canvas>
</div>
<button id="screenshot-btn">截图</button>
<img id="screenshot" src="" alt="screenshot">
核心代码是确定截取坐标及大小。
// 定义截图函数
async function takeScreenshot() {// 获取视频元素const video = document.getElementById('v1');// 获取 mrz 区域的位置和尺寸const mrzRect = document.getElementById('mrz').getBoundingClientRect();const mrzWidth = mrzRect.width;const mrzHeight = mrzRect.height;// 设置 canvas 大小为 mrz 区域的大小const canvas = document.getElementById('captureCanvas');canvas.width = mrzWidth;canvas.height = mrzHeight;// 获取 canvas 的 2D 上下文const ctx = canvas.getContext('2d');// 清除 canvasctx.clearRect(0, 0, canvas.width, canvas.height);// 获取视频元素的位置const videoRect = video.getBoundingClientRect();// 获取 mrz 区域相对于视频的位置const mrzX = mrzRect.left - videoRect.left;const mrzY = mrzRect.top - videoRect.top;// 计算视频流的像素比例const videoScaleX = videoRect.width / video.videoWidth;const videoScaleY = videoRect.height / video.videoHeight;// 计算原始视频坐标const originalMrzX = Math.round(mrzX / videoScaleX);const originalMrzY = Math.round(mrzY / videoScaleY);// 确保原始坐标正确const finalMrzX = Math.max(0, originalMrzX);const finalMrzY = Math.max(0, originalMrzY);// 使用 drawImage 方法绘制指定区域到 canvas 上ctx.drawImage(video,finalMrzX, finalMrzY, // 源图像的起始坐标mrzWidth / videoScaleX, mrzHeight / videoScaleY, // 源图像的宽度和高度0, 0, // 目标图像的起始坐标mrzWidth, mrzHeight // 目标图像的宽度和高度);// 生成图片const dataUrl = canvas.toDataURL();document.getElementById('screenshot').src = dataUrl;
}
最关键的就是这段代码:
// 使用 drawImage 方法绘制指定区域到 canvas 上ctx.drawImage(video,finalMrzX, finalMrzY, // 源图像的起始坐标mrzWidth / videoScaleX, mrzHeight / videoScaleY, // 源图像的宽度和高度0, 0, // 目标图像的起始坐标mrzWidth, mrzHeight // 目标图像的宽度和高度);
实际应用的时候可能截取的区域不是很准确,有偏差,这时候可以通过调整起始坐标位置和源图像的宽高,来调整截图区域,使截出来的图片更准确。