javascript - 使用设备摄像头在 reactjs 中捕获图像

标签 javascript reactjs camera progressive-web-apps webcam

我可以访问设备相机并在 ReactJs 中拍照吗?目标是创建一个组件,允许相机通过单击按钮来拍照。根据我的研究,我应该使用 mediaDevices,但我正在寻找 ReactJs 中的示例代码。请向我提供示例代码,或者如果您有实现此代码的经验,请指导我。

最佳答案

我准备了一个可以用作组件的示例代码。此代码段适用于也有两个摄像头的设备。如果您想拍摄视频而不是照片,您还可以在输出中启用音频功能。

import React from "react";

class App extends React.Component {
  constructor() {
    super();

    this.cameraNumber = 0;

    this.state = {
      imageDataURL: null,
    };
  }

  initializeMedia = async () => {
    this.setState({ imageDataURL: null });

    if (!("mediaDevices" in navigator)) {
      navigator.mediaDevices = {};
    }

    if (!("getUserMedia" in navigator.mediaDevices)) {
      navigator.mediaDevices.getUserMedia = function (constraints) {
        var getUserMedia =
          navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

        if (!getUserMedia) {
          return Promise.reject(new Error("getUserMedia Not Implemented"));
        }

        return new Promise((resolve, reject) => {
          getUserMedia.call(navigator, constraints, resolve, reject);
        });
      };
    }

    //Get the details of video inputs of the device
    const videoInputs = await this.getListOfVideoInputs();

    //The device has a camera
    if (videoInputs.length) {
      navigator.mediaDevices
        .getUserMedia({
          video: {
            deviceId: {
              exact: videoInputs[this.cameraNumber].deviceId,
            },
          },
        })
        .then((stream) => {
          this.player.srcObject = stream;
        })
        .catch((error) => {
          console.error(error);
        });
    } else {
      alert("The device does not have a camera");
    }
  };

  capturePicture = () => {
    var canvas = document.createElement("canvas");
    canvas.width = this.player.videoWidth;
    canvas.height = this.player.videoHeight;
    var contex = canvas.getContext("2d");
    contex.drawImage(this.player, 0, 0, canvas.width, canvas.height);
    this.player.srcObject.getVideoTracks().forEach((track) => {
      track.stop();
    });

    console.log(canvas.toDataURL());
    this.setState({ imageDataURL: canvas.toDataURL() });
  };

  switchCamera = async () => {
    const listOfVideoInputs = await this.getListOfVideoInputs();

    // The device has more than one camera
    if (listOfVideoInputs.length > 1) {
      if (this.player.srcObject) {
        this.player.srcObject.getVideoTracks().forEach((track) => {
          track.stop();
        });
      }

      // switch to second camera
      if (this.cameraNumber === 0) {
        this.cameraNumber = 1;
      }
      // switch to first camera
      else if (this.cameraNumber === 1) {
        this.cameraNumber = 0;
      }

      // Restart based on camera input
      this.initializeMedia();
    } else if (listOfVideoInputs.length === 1) {
      alert("The device has only one camera");
    } else {
      alert("The device does not have a camera");
    }
  };

  getListOfVideoInputs = async () => {
    // Get the details of audio and video output of the device
    const enumerateDevices = await navigator.mediaDevices.enumerateDevices();

    //Filter video outputs (for devices with multiple cameras)
    return enumerateDevices.filter((device) => device.kind === "videoinput");
  };

  render() {
    const playerORImage = Boolean(this.state.imageDataURL) ? (
      <img src={this.state.imageDataURL} alt="cameraPic" />
    ) : (
      <video
        ref={(refrence) => {
          this.player = refrence;
        }}
        autoPlay
      ></video>
    );

    return (
      <div className="App">
        {playerORImage}
        <button onClick={this.initializeMedia}>Take Photo</button>
        <button onClick={this.capturePicture}>Capture</button>
        <button onClick={this.switchCamera}>Switch</button>
      </div>
    );
  }
}

export default App;

关于javascript - 使用设备摄像头在 reactjs 中捕获图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64341977/

相关文章:

Android 谷歌地图 v2 相机动画

c++ - 如何在现代 opengl 中正确实现四元数相机?

android - 使用 Android Camera2,应用会无限期地卡在 STATE_WAITING_PRECAPTURE 或 STATE_WAITING_NON_PRECAPTURE

javascript - 扩展 jQuery 插件,无需触及原始插件代码

javascript - 提交 AJAX Post onchange

svg - 如何使用 d3 生成 svg 客户端而不将其附加到 DOM(与 React.js 一起使用)

javascript - console.log 变量时 target.dispatchEvent 上的 TypeError

javascript - 如何在事件上创建 DOM 元素,然后阻止事件处理程序触发,直到 DOM 元素存在?

javascript - OpenLayers 中的 Flash 动画不是连续渲染的

javascript - ReactJS - 如何将数据从子组件获取到在 Prop 中传递的按钮的 onclick 中?