You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将摄像头人脸检测截图保存至JavaScript脚本同目录?

能否将网页捕获的人脸截图保存至JS文件所在的同一目录?

我用VS Code启动本地服务器,借助faceapi JavaScript库检测摄像头视频流里的人脸。程序会加载必要的人脸检测模型,在canvas上显示带检测框的实时视频,还做了个按钮可以捕获带人脸标记的截图并存为PNG文件,但现在图片默认存到浏览器的下载文件夹,想问能不能把截图存到JS文件所在的同一目录?

const screenshotButton = document.getElementById('screenshotButton');

Promise.all([
  faceapi.nets.tinyFaceDetector.loadFromUri('/models'),
  faceapi.nets.faceLandmark68Net.loadFromUri('/models'),
  faceapi.nets.faceRecognitionNet.loadFromUri('/models'),
  faceapi.nets.faceExpressionNet.loadFromUri('/models')
]).then(startVideo);

function startVideo() {
  navigator.getUserMedia(
    { video: {} },
    stream => video.srcObject = stream,
    err => console.error(err)
  );
}

video.addEventListener('play', () => {
  const canvas = faceapi.createCanvasFromMedia(video);
  document.body.append(canvas);
  const displaySize = { width: video.width, height: video.height };
  faceapi.matchDimensions(canvas, displaySize);
  setInterval(async () => {
    const detections = await faceapi.detectAllFaces(video, new faceapi.TinyFaceDetectorOptions()).withFaceLandmarks().withFaceExpressions();
    const resizedDetections = faceapi.resizeResults(detections, displaySize);
    canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height);
    faceapi.draw.drawDetections(canvas, resizedDetections);
  }, 100);

  screenshotButton.addEventListener('click', async () => {
    const detections = await faceapi.detectAllFaces(video, new faceapi.TinyFaceDetectorOptions()).withFaceLandmarks().withFaceExpressions();
    if (detections.length > 0) {
      const canvas = faceapi.createCanvasFromMedia(video);
      document.body.append(canvas);
      const displaySize = { width: video.width, height: video.height };
      faceapi.matchDimensions(canvas, displaySize);
      const resizedDetections = faceapi.resizeResults(detections, displaySize);
      canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height);
      faceapi.draw.drawDetections(canvas, resizedDetections);
      const context = canvas.getContext('2d');
      context.drawImage(video, 0, 0, canvas.width, canvas.height);
      const dataURL = canvas.toDataURL('image/png');
      const link = document.createElement('a');
      link.download = `screenshot-${new Date().toISOString()}.png`;
      link.href = dataURL;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      document.body.removeChild(canvas); // Remove the canvas after taking the screenshot
    } else {
      alert('No face detected in the video. Please position your face in front of the camera and try again.');
    }
  });
});

核心结论

浏览器环境下的前端JavaScript无法直接自动将文件写入本地或服务器的任意目录,这是浏览器的安全机制限制,防止恶意网页随意操作用户文件系统。以下是两种可行的变通方案:

方案1:本地开发环境下用Node.js后端辅助保存

如果是自己本地开发测试,可以写一个简单的Node.js后端接口,前端把截图数据传给后端,由后端写入到JS文件所在的目录:

  1. 新建server.js文件,用Express搭建服务:
const express = require('express');
const fs = require('fs');
const path = require('path');
const app = express();
app.use(express.json({ limit: '10mb' }));

// 接收截图数据并保存
app.post('/save-screenshot', (req, res) => {
  const { base64Data, filename } = req.body;
  // 移除base64前缀并转成Buffer
  const buffer = Buffer.from(base64Data.replace(/^data:image\/png;base64,/, ''), 'base64');
  // 保存到当前服务文件所在目录(可根据实际路径调整)
  const savePath = path.join(__dirname, filename);
  fs.writeFile(savePath, buffer, (err) => {
    if (err) return res.status(500).send('保存失败');
    res.send('截图已保存到目标目录');
  });
});

app.listen(3000, () => console.log('后端服务运行在http://localhost:3000'));
  1. 修改前端截图按钮的逻辑,替换原来的下载链接代码:
// 原link.click相关代码替换为:
const base64Data = dataURL.replace(/^data:image\/png;base64,/, '');
fetch('http://localhost:3000/save-screenshot', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    base64Data,
    filename: `screenshot-${new Date().toISOString()}.png`
  })
}).then(res => res.text()).then(msg => alert(msg));

方案2:使用浏览器文件系统访问API(需用户手动确认)

现代浏览器支持文件系统访问API,允许用户手动选择保存目录,你可以引导用户选择JS文件所在的目录后保存:

修改前端截图逻辑:

// 原link.click相关代码替换为:
const blob = await fetch(dataURL).then(res => res.blob());
// 弹出保存文件选择框
const handle = await window.showSaveFilePicker({
  suggestedName: `screenshot-${new Date().toISOString()}.png`,
  types: [{
    description: 'PNG图片',
    accept: { 'image/png': ['.png'] }
  }]
});
// 写入文件
const writable = await handle.createWritable();
await writable.write(blob);
await writable.close();
alert('截图保存成功');

注意:这个API必须由用户主动触发(比如点击按钮),且需要用户手动选择保存目录,无法自动直接写入目标目录,这是浏览器的安全要求。


内容的提问来源于stack exchange,提问作者Ken Robertson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 14:43:16