[React] React Webcam のカメラ映像をimgタグの画像に変換してみる

準備

React Webcam のインストールなどはこちら。

カメラ映像から画像を取得して表示する

写真を撮るようなイメージで、ボタンを押したときの映像を img タグ で表示してみます。
いつものように App.js を編集します。

import Webcam from "react-webcam";
import React, { useEffect, useRef, useState } from 'react';
import './App.css';
import Dropdown from "./components/Dropdown";
import Button from "./components/Button";

function App() {

  const [cameras, setCameras] = useState([]);
  const [camera, setCamera] = useState(null);

  const [url, setUrl] = useState(null);

  const webcamRef = useRef(null);

  useEffect(() => {
    navigator.mediaDevices.enumerateDevices().then(mediaDevices => {
      const devices = mediaDevices.filter(({ kind }) => kind === "videoinput");
      setCameras(devices);
      if (devices.length) {
        setCamera(devices[0]);
      }
    })
  }, [])

  const handleClick = (cb) => {
    const imageSrc = webcamRef.current?.getScreenshot({ width: webcamRef.current.video.videoWidth, height: webcamRef.current.video.videoHeight });
    if (!imageSrc) {
      cb();
      return;
    }
    setUrl(imageSrc);
    cb();
  };

  return (
    <>
      <div className="bg-dark" style={{ minHeight: '100vh' }}>
        <div className="p-5 text-center">
          <Dropdown
            className="mb-4"
            variant="success"
            title={camera ? camera?.label : 'カメラが見つかりませんでした。'}
            items={cameras?.map(_camera => {
              return {
                children: _camera?.label,
                className: _camera?.deviceId === camera?.deviceId ? 'disabled' : '',
                onClick: () => setCamera(_camera),
              };
            })}
          />
          <div className="d-flex justify-content-center align-items-center">
            <Webcam
              ref={webcamRef}
              videoConstraints={{
                width: 320,
                height: 240,
                deviceId: camera?.deviceId,
              }}
              className="border border-light"
              style={{ width: 320, height: 240, boxSizing: 'content-box' }}
            />
            <Button className="mx-4" onClick={handleClick}>→</Button>
            <div className="border border-light" style={{ minWidth: 320, minHeight: 240 }}>
              {
                url && (
                  <img src={url} alt="camera image" />
                )
              }
            </div>
          </div>
        </div>
      </div>
    </>
  );
}

export default App;

動かしてみます。
左がカメラ、右がimgタグ。

はい、できました。


ここにコードがないコンポーネントは、過去の記事にあります ('◇’)ゞ