目标,截取红色色块背后的视频区域。
代码结构如下:
<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');
// 清除 canvas
ctx.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 // 目标图像的宽度和高度
);
实际应用的时候可能截取的区域不是很准确,有偏差,这时候可以通过调整起始坐标位置和源图像的宽高,来调整截图区域,使截出来的图片更准确。