如何在Canvas上翻转摄像头视频同时不反转画布上绘制的文字等内容
解决方案
核心是用Canvas上下文的save()/restore()方法隔离镜像变换的作用范围,不需要额外叠加画布。
实现逻辑
ctx.save()可以暂存当前上下文的所有状态(包括变换矩阵、样式配置等)- 仅在绘制摄像头视频时应用
translate+scale的镜像变换 - 视频绘制完成后立刻调用
ctx.restore()恢复状态,后续文字、标记的绘制完全不受镜像影响 - 注意:姿态检测返回的坐标是原始未镜像的视频坐标,需要手动换算x轴坐标适配镜像后的视频位置:
镜像后x = 画布宽度 - 原始x坐标
修改后的代码
const setupcamera = () => { navigator.mediaDevices .getUserMedia({ video: { width: 600, height: 400 }, audio: false, }) .then((stream) => { video.srcObject = stream; }); }; const detectpose = async () => { const poses = await detector.estimatePoses(video, false); console.log(poses); // 仅绘制视频时应用镜像,与其他绘制隔离 ctx.save(); ctx.translate(600, 0); ctx.scale(-1, 1); ctx.drawImage(video, 0, 0, 600, 400); ctx.restore(); // 后续绘制均为正常方向 ctx.font = "30px Comic Sans MS"; ctx.fillStyle = "green"; // 姿态坐标x轴镜像适配 const adjustedElbowX = 600 - elbowx; ctx.fillText(po, adjustedElbowX, elbowy); }; setupcamera(); video.addEventListener("loadeddata", async () => { // 移除全局的变换配置 detector = await poseDetection.createDetector( poseDetection.SupportedModels.MoveNet ); setInterval(detectpose, 20); });
内容的提问来源于stack exchange,提问作者LELOUCH
相关产品推荐
相关产品推荐

