Raspberry Pi のカメラモジュールとNode.jsで写真を撮る


Raspberry Piのカメラモジュールを使った写真撮影の覚え書きです。Node.jsのexpressを利用します。

## 環境

- Raspberry Pi2 ModelB （raspbian-Jessie・Node.js v4.2.4）
- PLANEX 無線LAN子機 (USBアダプター型) GW-USNANO2A (FFP)
- Raspberry Pi カメラモジュール Raspberry Pi Camera Board
- Raspberry Pi カメラモジュール専用　Blackケース

<a href="http://www.amazon.co.jp/exec/obidos/ASIN/B00KAAEBWI/pondadamazoz-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/417-8P11GCL.jpg" alt="Raspberry Pi カメラモジュール Raspberry Pi Camera Board" style="border: none;" /></a>

カメラモジュール用の保護ケースを取り付けるとこのようになります。

![DSC_0008 (1).jpg](https://qiita-image-store.s3.amazonaws.com/0/47128/fdb344c4-7219-85c3-fe42-769323bafa48.jpeg)

## 基本のコマンドラインツール

Raspberry Piの公式ドキュメントによると、カメラモジュールの静止画は以下のコマンドラインで撮影可能になっています。

```bash:ssh
raspistill -o cam.jpg
```

`-o cam.jpg`でファイル名を指定して撮影、保存まで簡単に行ってくれます。

その他オプション指定により、画像の大きさ、品質などを指定出来ます。タイムラプス撮影も標準で撮影出来る様になっています。

## Node.jsで撮影・プレビュー

bashスクリプトを利用した撮影・プレビューは公式ドキュメントに載っています。今回はブラウザから撮影・プレビューをする為Node.jsのexpressを利用しました。

任意のディレクトリで以下コマンドを実施します。（今回はexpress generatorを利用します。モジュールは導入済みとします。）

```bash:ssh
$ express -e camera
$ cd camera && npm install
$ DEBUG=camera:* npm start
```

これで標準の雛形が作られます。今回は撮影画面をデフォルトの`index.ejs`として、画像のプレビュー画面を`preview.ejs`として追加しました。

基本のファイル構成はそのまま利用します。

![Raspberry Pi 2016-03-12 23-07-39.png](https://qiita-image-store.s3.amazonaws.com/0/47128/fb62a2e1-771b-b3a9-e317-1ebf8fa951da.png)

```js:routes/index.js

//expressの使用許可
var express = require('express');
var router = express.Router();

//コマンドラインを利用する為child_processの使用許可
var spawn = require('child_process').spawn;

//ホーム画面index.ejsの表示
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Ras Pi Cam' });
});

//シヤッターボタンクリック時の処理
router.get('/shutter', function (req, res) {
  console.log(req.query);
  var id = req.query.id;

var raspistill = spawn('raspistill', [ '-o' , './public/images/raspi.jpg']);

raspistill.stdout.on('data', function (data) {
  console.log('stdout: ' + data);
});

raspistill.stderr.on('data', function (data) {
  console.log('stderr: ' + data);
});

raspistill.on('close', function (code) {
  console.log('child process exited with code ' + code);
});

});


//プレビュー画面preview.ejsの表示
router.get('/preview', function(req, res, next) {
  res.render('preview', { title: 'Ras Pi Cam' });
});

module.exports = router;

```

express generatorを利用すると、`app.js`でクライアント側の面倒な画像ファイル・CSS・jsの読み込み指定をしてくれます。

ここでは撮影用の画面`index.js`とプレビュー用の画面`preview.ejs`の指定と撮影画面でボタンをクリックした際に撮影コマンド`raspistill`を実行させる処理をこの`index.js`に記述しました。

```html:views/index.ejs
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="content-type"
        content="text/html; charset=UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0,user-scalable=no">
    <title><%= title %></title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" type="text/css" />
   <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <header>
        <h1 class="text-center h2"><%=title %></h1>
    </header>
    <article class="text-center">
      <button class="btn btn-default" id="shutter">Shutter</button>
      <a class="btn btn-default" role="button" href="/preview">Preview</a>

    </article>
    <script src="http://code.jquery.com/jquery-2.2.1.min.js"></script>
    <script src="/javascripts/main.js"></script>
  </body>
</html>

```

```js:public/javascripts/main.js
$("#shutter").click(function() {
        $.get("http://192.168.0.10:3000/shutter", { id: 'shutter' } );
    });

```

```css:public/stylesheets/style.css
body {
  margin: 0 auto;
  max-width: 640px;
  font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
}

article{
  padding: 50px;
}

a {
  color: #00B7FF;
}

```

![Ras Pi Cam 2016-03-12 23-25-11.png](https://qiita-image-store.s3.amazonaws.com/0/47128/f252e74b-5aa0-d721-41da-6eef24985b71.png)

シャッターボタンをクリックすると`index.js`にGETリクエストを送信します。

プレビューボタンは`preview.ejs`にリンクするようにしました。

```html:views/preview.ejs
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="content-type"
        content="text/html; charset=UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0,user-scalable=no">
    <title><%= title %></title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" type="text/css" />
   <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <header>
        <h1 class="text-center h2"><%=title %></h1>
    </header>
    <article class="text-center">
      <img class="img-responsive" src="/images/raspi.jpg">
      <br>
      <a class="btn btn-default" href="/" role="button">Back</a>

    </article>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
    <script src="/javascripts/main.js"></script>
  </body>
</html>


```

![Ras Pi Cam 2016-03-13 00-02-29.png](https://qiita-image-store.s3.amazonaws.com/0/47128/2c5b8fcc-6cb4-c122-01f3-5a2ef2c4abbf.png)

画像の保存先は`./public/images/raspi.jpg`とパブリックフォルダに保存します。

表示させる時はexpressの`app.js`でpublicフォルダの読み込み指定をしているので、`/images/raspi.jpg`で読み込めます。


## 参考にさせていただきました

[Raspberry piのカメラモジュールで撮影した画像をnode.jsで立てたサーバーに表示する](http://d.hatena.ne.jp/seinzumtode/20130921/1379742743)

[Raspberry PiのカメラモジュールをJavaScript(Node.js)で制御する](http://denshibu.blog.fc2.com/blog-entry-25.html)