JavaScriptでPCのカメラを使ったりする方法−其の壱−カメラを一つだけ使う

この記事はパソコンやスマートフォンのカメラをJavaScriptで制御する方法のメモである。

まずは、ラップトップパソコンやタブレットPCなど、カメラが1つだけのとき、または複数あるときのデフォルトのカメラを使う時の方法である。

決めておくこと

カメラを制御するときには、いくつか決めておくことがある。

画素数

カメラを使うときには、2つの画素数を決める。

撮影する画像の大きさ

ひとつはカメラで撮影する画像の縦と横の画素数である。この画素数で撮影したデータを画像データとして出力できる。

ファインダーの大きさ

もうひとつはファインダーの縦と横の画素数である。ファインダーはカメラがどんな画像を写しているかを確かめるために使う。

ソースコード

HTMLとJavaScriptそれぞれのソースコードはこのようになる。

HTMLのソースコード

<video id="cameraFinder" autoplay></video>
<input type="button" value="シャッター" onclick="pressShutter()"><br>
撮影した画像<br>
<canvas id="canvasDetector"></canvas>
<img id="imgDetector">
タグ名内容
videoカメラのファインダーとして使う。
inputシャッターボタンとして使う。
canvas撮影した画像を表示する。
img撮影した画像を表示する。
画像を表示するタグにはcanvasとimgが挙げられるので、撮影した画像をそれぞれに表示してみる。

JavaScriptのソースコード

JavaScriptのコードはこのようになる。

  //撮影する画像の大きさ
  const CAMERA_IMG_WIDTH  = 600;
  const CAMERA_IMG_HEIGHT = 450;

  //ファインダーの大きさ
  const FINDER_WIDTH  = 300;
  const FINDER_HEIGHT = 225;

  //カメラの仕様の定義
  const cameraSpec = {
    audio: false,
    video: {
      width : CAMERA_IMG_WIDTH  ,
      height: CAMERA_IMG_HEIGHT
    }
  };

  //カメラを使えるようにする
  navigator.mediaDevices.getUserMedia(cameraSpec)
    .then((stream) => {
      openFinder(stream);
    })


  /**
   * カメラファインダーの表示
   */
  function openFinder(stream) {
    //ファインダーとして使うvideoタグの画素数の指定
    let finderElement = document.getElementById("cameraFinder");
    finderElement.style.width  = FINDER_WIDTH  + "px";
    finderElement.style.height = FINDER_HEIGHT + "px";

    //videoタグにカメラが見ている画像を表示
    finderElement.srcObject = stream;
    finderElement.onloadedmetadata = (e) => {
      finderElement.play();
    };
  }


  /**
   * シャッターボタン押下
   */
  function pressShutter() {
    let finderElement = document.getElementById("cameraFinder");

    // 演出的な目的で一度映像を止めてSEを再生する
    finderElement.pause();  // 映像を停止
    setTimeout(() => {
      finderElement.play();    // 0.5秒後にカメラ再開
    }, 500);


    //撮影した画像をcanvasタグに表示
    let canvasPhoto = document.getElementById("canvasDetector");
    //canvasタグの大きさ
    canvasPhoto.style.width  = CAMERA_IMG_WIDTH  + "px";
    canvasPhoto.style.height = CAMERA_IMG_HEIGHT + "px";
    //カンバス自体の大きさ
    canvasPhoto.width  = CAMERA_IMG_WIDTH;
    canvasPhoto.height = CAMERA_IMG_HEIGHT;
    //canvasタグへ表示の本体
    canvasPhoto.getContext("2d").drawImage(
      finderElement,
      0, 0, CAMERA_IMG_WIDTH ,CAMERA_IMG_HEIGHT , //画像のどの範囲を表示するか
      0, 0, CAMERA_IMG_WIDTH ,CAMERA_IMG_HEIGHT   //カンバスのどの範囲に表示するか
    );


    //imgタグに表示するとき
    let imgPhoto = document.getElementById("imgDetector");
    //imgタグの大きさ
    imgPhoto.style.width  = CAMERA_IMG_WIDTH  + "px";
    imgPhoto.style.height = CAMERA_IMG_HEIGHT + "px";

    imgPhoto.src = canvasPhoto.toDataURL();
  }

このコードがどうなっているのかをみていこう。

定義部分

  //撮影する画像の大きさ
  const CAMERA_IMG_WIDTH  = 600;
  const CAMERA_IMG_HEIGHT = 450;

  //ファインダーの大きさ
  const FINDER_WIDTH  = 300;
  const FINDER_HEIGHT = 225;

  //カメラの仕様の定義
  const cameraSpec = {
    audio: false,
    video: {
      width : CAMERA_IMG_WIDTH  ,
      height: CAMERA_IMG_HEIGHT
    }
  };
項目内容
撮影する画像の大きさ撮影する画像の縦と横の画素数を定義する。
ファインダーの大きさファインダーとして使うタグの縦と横の画素数を定義する。
カメラの仕様の定義カメラの仕様を定義する。

「カメラの仕様の定義」にはいくつかの項目がある。

項目内容
audio音声を使うかどうかを指定する。今回は使わないのでfalseにする。
videoのwidthとheight撮影する画像の縦と横の画素数を定義する。「撮影する画像の大きさ」の値を使う。
videoのfacingModeスマートフォンのようにカメラが2台以上あるとき、どのカメラを使うかを指定する。

カメラを使えるようにする

  //カメラを使えるようにする
  navigator.mediaDevices.getUserMedia(cameraSpec)
    .then((stream) => {
      openFinder(stream);
    })


  /**
   * カメラファインダーの表示
   */
  function openFinder(stream) {
    //ファインダーとして使うvideoタグの画素数の指定
    let finderElement = document.getElementById("cameraFinder");
    finderElement.style.width  = FINDER_WIDTH  + "px";
    finderElement.style.height = FINDER_HEIGHT + "px";

    //videoタグにカメラが見ている画像を表示
    finderElement.srcObject = stream;
    finderElement.onloadedmetadata = (e) => {
      finderElement.play();
    };
  }

navigator.mediaDevices.getUserMedia()にカメラの仕様を指定するとカメラを使えるようになる。
navigator.mediaDevices.getUserMedia()が正常終了したときの戻り値を使ってファインダーを表示する。ここでは別関数(openFinder())で表示する。

カメラファインダーの表示では、ファインダーとして使うvideoタグの縦と横の画素数を指定し、srcObjectにnavigator.mediaDevices.getUserMedia()の戻り値を指定する。続けてvideoタグのplay()でカメラに写っている画像がファインダーに表示される。

シャッターボタンの押下

  /**
   * シャッターボタン押下
   */
  function pressShutter() {
    let finderElement = document.getElementById("cameraFinder");

    // 演出的な目的で一度映像を止めてSEを再生する
    finderElement.pause();  // 映像を停止
    setTimeout(() => {
      finderElement.play();    // 0.5秒後にカメラ再開
    }, 500);


    //撮影した画像をcanvasタグに表示
    let canvasPhoto = document.getElementById("canvasDetector");
    //canvasタグの大きさ
    canvasPhoto.style.width  = CAMERA_IMG_WIDTH  + "px";
    canvasPhoto.style.height = CAMERA_IMG_HEIGHT + "px";
    //カンバス自体の大きさ
    canvasPhoto.width  = CAMERA_IMG_WIDTH;
    canvasPhoto.height = CAMERA_IMG_HEIGHT;
    //canvasタグへ表示の本体
    canvasPhoto.getContext("2d").drawImage(
      finderElement,
      0, 0, CAMERA_IMG_WIDTH ,CAMERA_IMG_HEIGHT , //画像のどの範囲を表示するか
      0, 0, CAMERA_IMG_WIDTH ,CAMERA_IMG_HEIGHT   //カンバスのどの範囲に表示するか
    );


    //imgタグに表示するとき
    let imgPhoto = document.getElementById("imgDetector");
    //imgタグの大きさ
    imgPhoto.style.width  = CAMERA_IMG_WIDTH  + "px";
    imgPhoto.style.height = CAMERA_IMG_HEIGHT + "px";

    imgPhoto.src = canvasPhoto.toDataURL();
  }

シャッターボタン押下時は、撮影時の画像をcanvasタグに表示できる。imgタグには直には表示できず、「canvasタグの内容を表示する」という方法になる。

canvasタグに撮影時の画像を表示するには、canvasタグのdrawImage()で、ファインダーとして使っているvideoタグを指定する。同時に表示する縦と横の画素数を指定しておく。

imgタグに撮影時の画像を表示するには、canvasタグの内容をtoDataURL()で変換してimgタグのsrcに指定する。


では、実際にカメラを表示し、撮影してみよう→「JavaScriptでPCのカメラを使ったりする方法−其の壱−カメラを一つだけ使う」を実行してみる

コメント

タイトルとURLをコピーしました