ev3devとWEBカメラでオリジナルカメラを作る【後編・プログラム解説】

## はじめに
EV3で動くLinux環境ev3devを使って開発します。この記事は、EV3にev3devをインストールし、SSH接続できている状態であることを前提にしています。
環境構築ができていない方はこちらの記事を参考にしてください。
>
[mindstorm-EV3をLinuxで制御しよう! ev3dev OSのインストールととSSH接続](http://qiita.com/murotani/items/46f905bec33b1673c41a)

この記事の前編はこちらです。後編ではプログラムについて解説します。
>
[ev3devとWEBカメラでオリジナルカメラを作る【前編】](http://qiita.com/murotani/items/9a1b121a4500faf9e0db)

##プログラム

###ファイル構成
前編での環境構築後のファイル構成はこのようになっているはずです。

```
robot@ev3dev:~/ev3Cam$ ls
index.html  index.js  node_modules  package.json
```

index.htmlがクライアント側（ブラウザ側）、index.jsがサーバー側です。

###index.js

```js:index.js
var http=require('http');
var server=http.createServer();
var io=require('socket.io').listen(server);
var fs=require('fs');
server.listen(1337);
var  exec=require('child_process').exec;
var ev3dev=require('ev3dev-lang');

var fileNumber=0;
var touchSensor=new ev3dev.TouchSensor(ev3dev.INPUT_1);

//タッチセンサーのイベント
touchSensor.registerEventCallback(function(error, touchInfo) {
  if(error) throw error;
  //タッチセンサーが離されたらWEBカメラから画像取得
  if(!touchInfo.lastPressed){
    exec('fswebcam -r 800x600 ' + "./images/" + fileNumber + '.png', function(err, stdout, stderr){
      if (err) { console.log(err); }
      imgFileName.emit('message',fileNumber+".png");
      fileNumber += 1;
    });
    console.log("take");
  }
  },
    function(userData) {
      var isPressed = touchSensor.isPressed;
      var changed = isPressed != userData.lastPressed;
      userData.lastPressed = isPressed;
      return changed;
    },
    false,
    { lastPressed: false }
);

//サーバーへのリクエストを処理 index.htmlと画像ファイルを配信する
server.on('request', function(req, res) {
  var url = req.url;
  if ('/' == url) {
    fs.readFile(__dirname + '/index.html', 'UTF-8', function (err, data) {
      res.writeHead(200, {'Content-Type': 'text/html'});
      res.write(data);
      res.end();
    });
  } else if (url.match(".png")) {
    fs.readFile(__dirname + req.url, function (err, data) {
      res.writeHead(200, {'Content-Type': 'image/png'});
      res.write(data);
      res.end();
    });
  }
})

var imgFileName=io.of('/imgFileName').on('connection',function(socket){
});
```
nodejsからシェルコマンドとしてfswebcamコマンドを実行しています。画像を保存したファイル名をソケット通信でブラウザ側に送信しています。画像はimagesディレクトリに保存されます。

```
exec('fswebcam -r 800x600 ' + "./images/" + fileNumber + '.png', function(err, stdout, stderr){
      if (err) { console.log(err); }
      imgFileName.emit('message',fileNumber+".png");
      fileNumber += 1;
    });
```
サーバーへのURLリクエストの処理。index.htmlと画像ファイルを静的に配信しています。

```
 if ('/' == url) {
    fs.readFile(__dirname + '/index.html', 'UTF-8', function (err, data) {
      res.writeHead(200, {'Content-Type': 'text/html'});
      res.write(data);
      res.end();
    });
  } else if (url.match(".png")) {
    fs.readFile(__dirname + req.url, function (err, data) {
      res.writeHead(200, {'Content-Type': 'image/png'});
      res.write(data);
      res.end();
    });
  }
```

###index.html

```html:index.html
<!Doctype html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <title>ev3Cam</title>
    <script src="/socket.io/socket.io.js"></script>
  </head>
  <body>
    <ul id="pictures"></ul>
  </body>
</html>
<script>
  var imgFileName=io.connect('http://ev3dev.local:1337/imgFileName');
  //ファイル名を受信 ファイルパスを指定してimgタグをつける
  imgFileName.on('message',function(fileName){
    console.log(fileName);
    var img = document.createElement('img');
    img.src = "./images/" + fileName ;
    document.getElementById('pictures').prepend(img)
  });
</script>
<style>
  h1{
    text-align:center;
  }
  img{
    width : 500px;
    display: block;
    margin-top: 100px;
    margin-left: auto;
    margin-right: auto;
  }
  p{
   text-align:center;
  }
</style>
```

ファイル名を受信してファイルパスにimgタグをつけることで画像を表示しています。

```
imgFileName.on('message',function(fileName){
    console.log(fileName);
    var img = document.createElement('img');
    img.src = "./images/" + fileName ;
    document.getElementById('pictures').prepend(img)
  });
```

##参考
[nodejsでmindstrom-EV3を制御するev3dev-lang-js入門](http://qiita.com/murotani/items/86921723020e4a537ed5)

[ev3dev-lang-jsとsocket.ioを使って簡単なwebアプリを作る](http://qiita.com/murotani/items/70470de079dd8a298d85)