Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
25
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

@qiita_mona

HTML5のWebRTCでPCに接続されたカメラ映像をウェブブラウザー上に表示してコマ画像を保存したい

PCに接続されたカメラ映像をウェブブラウザー上に表示する

【目的】
PCに接続されたカメラの映像を分析するシステムを開発する。
HTML5やら、javascriptやらを使ってシンプルに映像取得、
静止画と保存したい。

【技術】
開発環境はWindows10です。映像は家電量販店で安く買える
USBカメラをUSB接続して使います。USBカメラからの映像を
ウェブブラウザー上に表示して、静止画としてダウンロード
保存できることの確認までやっていきます。今回はウェブサーバー
を立ち上げませんが、サーバーにソースを置く場合は、
ブラウザのセキュリティーポリシーに従ってURLを指定
しないと動作しません。(今回は気にする必要ありません)

システムの実装

実装は、HTML5でWebRCT(Web Real-Time Communication)を使います。
基本的なjavascript言語の知識も必要です。

※ MediaDevices.getUserMedia() の使い方は下記を参照。
https://developer.mozilla.org/ja/docs/Web/API/Navigator/getUserMedia

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>getUserMedia-Demo</title>
</head>
<body>

<!-- カメラ映像が描画されます。 -->
<video id="video_area" style="background-color: #000" autoplay></video>

<!-- 押下するとカメラ映像描画を開始します。 -->
<button id="start_btn">映像表示開始</button>

</body>
<script>

    // getUserMedia が使えないときは、『getUserMedia()が使えないブラウザだよ』と言ってね。
    if (typeof navigator.mediaDevices.getUserMedia !== 'function') {
        const err = new Error('getUserMedia()が使えないブラウザだよ');
        alert(`${err.name} ${err.message}`);
        throw err;
    }

    // 操作する画面エレメント変数定義します。
    const $start = document.getElementById('start_btn');   // スタートボタン
    const $video = document.getElementById('video_area');  // 映像表示エリア

    // 「スタートボタン」を押下で、getUserMedia を使って映像を「映像表示エリア」に表示するよ。
    $start.addEventListener('click', () => {
        navigator.mediaDevices.getUserMedia({ video: true, audio: false })
        .then(stream => $video.srcObject = stream)
        .catch(err => alert(`${err.name} ${err.message}`));
    }, false);

</script>

</html>

上記のHTMLを『camdemo.html』の名称でUTF-8エンコードで保存します。
USBカメラが接続されているPCで、Chromeブラウザーで直接開いてみてください。

image.png

『映像表示開始』ボタンを押下します。

image.png

カメラを使用するので、「許可」します。

image.png

はい、映像が表示されました。
映像は静止画ではなく、動画映像として、表示されます。

映像から静止画(コマ画像)をcanvasエリアに表示します。

映像のコマ画像を、画面上の別のエリアに静止画として表示するコードを追加していきます。

実装はシンプルです。
1.「静止画キャプチャ」ボタンを追加します。
2.キャプチャーした静止画を表示するエリアを追加します。
3.(1.)のボタン押下で(2.)のエリアに画像を表示するコードを追加します。


<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>getUserMedia-Demo</title>
</head>
<body>

    <!-- カメラ映像が描画されます。 -->
    <video id="video_area" style="background-color: #000" autoplay></video>

    <!-- 押下するとカメラ映像描画を開始します。 -->
    <button id="start_btn">映像表示開始</button>

    <!-- 押下するとカメラ映像から静止画をキャプチャします。 -->
    <button onclick="copyFrame()">静止画取得</button>

    <!-- キャプチャした静止画が描画されます。 -->
    <canvas id="capture_image"></canvas>

</body>
<script>

    // getUserMedia が使えないときは、『getUserMedia()が利用できないブラウザです!』と言ってね。
    if (typeof navigator.mediaDevices.getUserMedia !== 'function') {
        const err = new Error('getUserMedia()が利用できないブラウザです!');
        alert(`${err.name} ${err.message}`);
        throw err;
    }

    // 操作する画面エレメント変数定義します。
    const $start = document.getElementById('start_btn');   // スタートボタン
    const $video = document.getElementById('video_area');  // 映像表示エリア

    // 「スタートボタン」を押下したら、getUserMedia を使って映像を「映像表示エリア」に表示してね。
    $start.addEventListener('click', () => {
        navigator.mediaDevices.getUserMedia({ video: true, audio: false })
        .then(stream => $video.srcObject = stream)
        .catch(err => alert(`${err.name} ${err.message}`));
    }, false);


    // 「静止画取得」ボタンが押されたら「<canvas id="capture_image">」に映像のコマ画像を表示します。
    function copyFrame() {

        var canvas_capture_image = document.getElementById('capture_image');
        var cci = canvas_capture_image.getContext('2d');
        var va = document.getElementById('video_area');

        canvas_capture_image.width  = va.videoWidth;
        canvas_capture_image.height = va.videoHeight;
        cci.drawImage(va, 0, 0);  // canvasに『「静止画取得」ボタン』押下時点の画像を描画。
    }


</script>

</html>

image.png

「静止画取得」ボタンを押下します。

image.png

「静止画取得」ボタンを押下した瞬間の映像が複写されました。
静止画なので、映像が変化しても一度キャプチャした映像は変わりません。

image.png

もう一度「静止画取得」ボタンを押下すれば、静止画も更新されます。

image.png

静止画側の画像の上で、マウス右クリックで「名前を付けて画像を保存」することができます。

image.png

Windows標準のペイントで開いてみました。こんな感じです。

image.png

また、『toDataURL() メソッド』を使って画像を所定の名称でダウンロード保存させることもできます。

それはまた次回。

以上です。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
25
Help us understand the problem. What are the problem?