javascriptでPC内蔵カメラで撮影した画像をサーバに送信
今回は、、、
・javascriptを用いて、PC内蔵カメラで写真撮影⇒サーバに送信
・nodejsでクライアントから送信されたデータを受信
の備忘録を書きたいと思います。
実は昔調べながら苦労して作ったことがあったのですが、忘れそうだったので備忘録として残したいと思い、書くことにしました!!
調べてもあまり出てこず、結構苦労した記憶があります。。。
画像をアップロードとかはいろんな人がやってるけど、内蔵カメラで取得したデータを、、、となると結構マイナーだもんね。。。
では初めて行きます!!
クライアントサイド
まずは、PC内蔵カメラの起動です。
html表示した時に自動でカメラ起動させたかったのでこのように実装。
window.onload = function Init(){ startVideo(); } function startVideo() { navigator.mediaDevices.getUserMedia({video: true, audio: false}) .then(function (stream) { document.getElementById('local_video').srcObject = stream; }).catch(function (error) { // 失敗時の処理はこちら. console.error('mediaDevice.getUserMedia() error:', error); return; }); }
重要なのはstartVideo関数!!こちらをコールすればカメラが起動します。
ここで、”local_video”とは、html側、videoタグのidとなります。
下記のように定義すれば、定義した位置にカメラで写った映像が表示されます。
<video id="local_video"autoplay style="width: 300px; height:200px; border: 1px solid black;"></video>
次にカメラ映像を画像として切り取ります!!
処理の流れとしては
①videoタグで映し出された映像を事前に定義しておいたcanvasに展開
②canvasに展開した画像をbase64に変換
③base64変換したデータのプレフィクスを削除
になります。
base64とは、エンコード方式の一種で64進数を意味しており、
すべてのデータをアルファベット(a~z, A~z)と数字(0~9)、一部の記号(+,/)の64文字で表す方式とのことです。
base64ってなんぞ??理解のために実装してみた - Qiita
なぜbase64に変換したか??ですが、
imageをそのままhttpで送信できないようで、エンコードする必要があるため実施しました。
では実際の実装はこちらとなります。
// javascriptでcanvas上に写真を function take_picture() { var canvas = document.getElementById('canvas'); // videoのstreamをcanvasに書き出す方法. var ctx = canvas.getContext('2d'); var w = video.offsetWidth * 0.5; // videoの横幅取得. var h = video.offsetHeight * 0.5; // videoの縦幅取得. canvas.setAttribute("width", w); // canvasに書き出すための横幅セット. canvas.setAttribute("height", h); // canvasに書き出すための縦幅セット. ctx.drawImage(video, 0, 0, w, h); // videoの画像をcanvasに書き出し. var base64 = canvas.toDataURL('image/jpg'); // canvas上の画像をbase64に変換. var picture = base64.replace(/^data:\w+\/\w+;base64,/, ''); // base64変換したデータのプレフィクスを削除. }
サーバサイド
このbase64にエンコードしたデータをサーバに送信してみます。
と言っても、エンコードしたデータをjson形式にして、ajaxを用いてpost送信するのみとなります!!
実装はこちらになります。
function tenso(picture){ return $.ajax({ url:"http://localhost:8080/camera",//phpファイルのURL type: "post", data: {"image":picture}, success: function(){ // 転送成功時. console.log("success"); }, error: function (XMLHttpRequest, textStatus, errorThrown) { // 転送失敗時. console.log("error"); } }) }
では次にサーバ側での受信についてです。
こちらは先ほど送信されたbase64でエンコードしたデータをデコードして画像に変換する処理となります。
今回は、デコードしたデータをpicture.jpgでファイル保存する時の処理をこちらに記載しました。
app.post('/camera',function(req, res) { fs.writeFile('picture.jpg',JSON.stringify(req.body.image),'base64',function(err); });
最後に
カメラを起動させるためにはlocalhostにするか、httpsでアクセスしなければなりません。
httpだとカメラ起動させることが出来ないです(セキュリティ的にNGのようです)。
実際にまとめてみると案外簡単な処理ですね。
やっていることは、
フロントサイド:カメラ起動⇒videoタグ上にカメラ映像表示⇒canvasに画像を展開⇒base64変換し送信
サーバサイド :base64から画像に変換し画像として保存
のみなので。
今回のと前回書いたopenfaceを連携させれば、顔認証とか出来て面白そうですねw。
elsammit-beginnerblg.hatenablog.com
やってみようかな?w