スマートフォンでカメラ画像を取得し JavaScript でエフェクト掛けてみた(その1:Camera API編)


# ■はじめに
Seriously.js, vignetteJSを利用してエフェクトの掛け方を調べたので、実際にカメラの画像にエフェクトを掛けてみました。

写真撮影〜エフェクト処理を JavaScript だけで実現します。

# ■アプリ作成

## 写真撮影

Firefox OS ではカメラを利用して写真(静止画)を撮影する為に以下の方法があります。

|API         |特徴           |権限   |
|------------|--------------|-------|
|[Camera API](https://developer.mozilla.org/ja/docs/DOM/Using_the_Camera_API)|プリインストールされているカメラアプリと連携し、写真を撮影することができる。使い方が非常に簡単。|Web|
|[getUserMedia](https://developer.mozilla.org/ja/docs/Web/API/Navigator/getUserMedia)|W3C にて策定されており、直接ウェブカメラやマイクから動画や音声を取得できる。|Web|
|[mozCamera](https://developer.mozilla.org/ja/docs/Web/API/Navigator/mozCamera)|プリインストールされているカメラアプリがカメラデバイスの制御に使用している。<br>その為、カメラアプリと同等のアプリが作成できる。<br>また、カメラアプリにはない機能を追加することができる|Privileged|

Camera API (と WebActivities )はカメラアプリに連携し、カメラアプリで写真を撮影することが出来ます。
その為、呼び出し側のアプリには写真撮影のための制御処理は必要なく実現が可能です。

一方、getUserMedia と mozCamera は自身でカメラアプリを作る際やリアルタイムにカメラ画像を利用する場合に利用することが出来ます。
両者ともに navigator 配下に属しており navigator.getUserMedia, navigator.mozCamera にて使用できます。

getUserMedia は W3C で策定された [Media Capture and Streams](http://www.w3.org/TR/mediacapture-streams/)そのもので、この API は Firefox OS に限らず他の環境(Chrome, Safariなど他のブラウザ)でも同様に使用することが可能です。

一方、mozCamera は Firefox OS 専用に用意された API となり、 Privileged 以上の権限でのみ使用可能となります(V2.0からとなります。それ以前は certified のみ使用可)。
両者の違いとして、画質が明らかに違うこと、利用できるメソッドに違いが存在します。


API が別なことも有り、それぞれの API で使用方法が異なります。
今回は Camera API についての使用方法を記載したいと思います。

## 処理フロー

camera API を使用した「写真撮影からエフェクト処理まで」の流れは以下となります。
<img src="https://qiita-image-store.s3.amazonaws.com/0/27642/91198fcd-23b3-b2bc-a21c-ce4cdb794c99.png" width="80%">

Camera API を利用してカメラアプリと連携し、写真撮影を行います。
その後、撮影した写真にエフェクトを掛ける流れとなります。

## Camera API

Camera API は以下のリンクが詳しいです。
https://developer.mozilla.org/ja/docs/DOM/Using_the_Camera_API


使い方は非常に簡単です。HTML に \<input\> タグを以下のように記載するだけです。

```
<input type="file" id="take-picture" accept="image/*">
```

id は JavaScript から参照するために必要なため、任意の名称にて記載して下さい。

実際に Firefox OS のスマートフォンで動かしてみると以下の様な図になります。
スクリーンショットは Fx0 ですｗ

<img src="https://qiita-image-store.s3.amazonaws.com/0/27642/7c75d693-9cc1-3e78-b935-dfdfc407c276.png" width=50%>

[参照]ボタンを押すと連携を行うアプリケーションの選択画面が表示されます。

<img src="https://qiita-image-store.s3.amazonaws.com/0/27642/24572ecd-86ba-7a3c-0bd4-278fd16e825b.png" width=50%>

ここでカメラを選択することでカメラアプリに連携します。

<img src="https://qiita-image-store.s3.amazonaws.com/0/27642/077958a3-b74a-85e8-6fc9-91b5a5aafe12.jpeg" width=50%>

カメラアプリで撮影すると、プレビュー画面が表示されます。

<img src="https://qiita-image-store.s3.amazonaws.com/0/27642/60482eb5-6b92-2bdc-d32a-153be86174e4.jpeg" width=50%>

ここで[選択]を選択することで撮影した写真が保存されます。

この後、遷移前のアプリに戻るのですが、アプリ側では以下の様に撮影完了を検知することが可能です。


```
var takePicture = document.querySelector("#take-picture");
takePicture.onchange = function (event) {
    // 撮影された写真または選択された画像への参照を取得
    var files = event.target.files,
        file;
    if (files && files.length > 0) {
        file = files[0];
    }
};
```

この取得したファイルパスにある画像をアプリ内の \<img\> タグの src に指定することでアプリ側で画像を表示可能です。
ここでは HTML 上で "source" という ID 名で \<img\> タグを定義していると想定して記載しています。

```
var takePicture = document.querySelector("#take-picture");
takePicture.onchange = function (event) {
    // 撮影された写真または選択された画像への参照を取得
    var files = event.target.files,
        file;
    if (files && files.length > 0) {
        file = files[0];
        var url = URL.createObjectURL(file);
        var img = document.getElementById('source');
        img.src = url;
        URL.revokeObjectURL(imgURL);
    }
};
```

あとは Seriously.js を利用してエフェクト処理を行います。


## エフェクト処理

エフェクト前

<img src="https://qiita-image-store.s3.amazonaws.com/0/27642/9100b048-94d2-ed96-8c01-3d32345fe428.jpeg" width=50%>

エフェクト処理後はこんな感じです。

<img src="https://qiita-image-store.s3.amazonaws.com/0/27642/676c40db-e776-fa65-baae-11e4e22214f5.jpeg" width=50%>


次回は getUserMedia を利用する方法に行きたいと思います。

03/26追記
http://qiita.com/YusukeYamamoto/items/2ffd3bc6951916a95988
に2回目を投稿しました!