SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Firefox OS搭載スマホ「Fx0」でつくろう! はじめてのFirefox OSアプリ開発(AD)

Firefox OSでCamera APIを利用したカメラアプリを作ろう ~カメラ関連APIの解説から実装、アプリの申請フローまで

Firefox OS搭載スマホ「Fx0」でつくろう! はじめてのFirefox OSアプリ開発 第2回

  • X ポスト
  • このエントリーをはてなブックマークに追加

カメラ機能の作成(2)

プレビューの表示

 次に、カメラのプレビューを画面に表示してみましょう。取得したCameraControlオブジェクトを<video>のストリームとしてmozSrcObjectプロパティにセットします。

index.html
<div id="previewContainer">
  <video id="preview"></video>
</div>
js/app.js
var previewVideo = document.getElementById('preview');

function onSuccess(success) {
  // スコープ外に値を保持
  camera = success;
  console.log('getCamera:success', camera);

  // プレビューの再生
  previewVideo.mozSrcObject = camera;
  previewVideo.play();
}

 プレビュー映像は、実際のアプリでは、取得した状態だと横向きに表示されてしまうため、<div>で<video>を囲い、CSSのtransformで回転させて縦向きの画像として見えるようにしています。

カメラからの画像の取得・保存

 実際にカメラの画像を保存するには、CameraControl.takePicture()を利用します。指定するオプションで画像サイズやファイルのフォーマット、EXIF情報などを指定することができます。

index.html
<span id="captureBtn" class="capture-btn"></span>
js/app.js
// ストレージ
var storage = navigator.getDeviceStorage('pictures');

// キャプチャボタン
var captureBtn = document.getElementById('captureBtn');
captureBtn.addEventListener('touchstart', captureStart, false);
captureBtn.addEventListener('touchend', captureEnd, false);

function captureStart(e) {
  console.log('captureStart', e);
  if(!camera) return;

  function onSuccess(success) {
    console.log('autoFocus:success', success);
  }

  function onError(error) {
    console.warn('autoFocus:error', error);
  }

  camera.autoFocus(onSuccess, onError);
}

function captureEnd(e) {
  console.log('captureEnd', e);
  if(!camera) return;

  var options = {
    pictureSize: camera.capabilities.pictureSizes[0], // 最大サイズ
    fileFormat: 'jpeg'
  };

  function onSuccess(success) {
    console.log('takePicture:success', success);

    // 画像をストレージへ保存
    var filename = 'fxcam_' + Date.now() + '.jpg';
    storage.addNamed(success, filename);

    alert("画像を保存しました\n" + filename);

    // プレビューの再開
    camera.resumePreview();
  };

  function onError(error) {
    console.log('takePicture:error', error);
    // カメラ取得失敗時の処理
  };

  camera.takePicture(options, onSuccess, onError);
}

 このコードでは、キャプチャボタンのtouchstart時にオートフォーカスで照準を合わせ、touchend時に撮影画像を取得します。

 カメラの画像を保存する際、取得できる画像サイズは端末のスペックに依存するため、CameraControlオブジェクトからカメラに関する情報をCameraCapabilitiesオブジェクトで受け取ります。

 画像が取得できると、成功時のコールバックにBlobオブジェクトとして画像が渡されます。BlobオブジェクトはDeviceStorage.addNamed()を利用してストレージに保存することができます。なお、ストレージへの初回アクセス時には、カメラへのアクセスと同様に、ユーザに対してAPI利用の承認画面が表示されます。

 また、CameraControl.takePicture()を呼ぶと、一旦プレビューが停止するため、CameraControl.resumePreview()でプレビュー映像を再開します。

Camera APIで利用できる画像のエフェクト処理

 CameraCapabilitiesオブジェクトには、画像に対するエフェクトも含まれています。

 エフェクトは、OSのバージョンや端末によって数が変わりますが、今回利用した端末では、以下の12つのプロパティがありました。

  • "none"(エフェクトなし)
  • "mono"(モノクロ調)
  • "negative"(ネガポジ反転)
  • "solarize"(ソラリゼーション)
  • "sepia"(セピア調)
  • "posterize"(ポスター絵調)
  • "whiteboard"(ホワイトボード:コントラスト強め)
  • "blackboard"(ブラックボード:コントラスト弱め)
  • "aqua"(アクア:青みがけ)
  • "emboss"(エンボス加工)
  • "sketch"(スケッチ風)
  • "neon"(ネオン)

 これらのプロパティをCameraControl.effectに指定することで、画像にエフェクトをかけることができます。プレビュー映像と、取得できる画像の両方にエフェクトが適用されます。

index.html
<span id="effectLabel" class="effect-label">none</span>
<span id="effectRightBtn" class="effect-right-btn">&rsaquo;</span>
<span id="effectLeftBtn" class="effect-left-btn">&lsaquo;</span>
js/app.js
// エフェクト
var effects = camera.capabilities.effects;
var effectIndex = 0;

// エフェクト名を表示するラベル
var effectLabel = document.getElementById('effectLabel');

// エフェクト切替ボタン(右)
var effectRightBtn = document.getElementById('effectRightBtn');
effectRightBtn.addEventListener('touchend', changeEffectRight, false);

// エフェクト切替ボタン(左)
var effectLeftBtn = document.getElementById('effectLeftBtn');
effectLeftBtn.addEventListener('touchend', changeEffectLeft, false);

function changeEffectRight(e) {
  console.log('changeEffectRight', effectIndex);
  if(!camera) return;

  effectIndex = (effectIndex < effects.length-1) ? effectIndex + 1 : 0;
  effectLabel.innerHTML = camera.effect = effects[effectIndex];
}

function changeEffectLeft(e) {
  console.log('changeEffectLeft', effectIndex);
  if(!camera) return;

  effectIndex = (effectIndex > 0) ? effectIndex - 1 : effects.length - 1;
  effectLabel.innerHTML = camera.effect = effects[effectIndex];
}

 上記のコードでは、エフェクトの切替ボタンを左右に配置し、それぞれを押すとエフェクトが順番に切り替わるようにしました。

実際のコード

 今回のアプリは、これだけのコードでカメラの制御とエフェクト加工が実現できます。もう少し整理したものをGitHubに公開していますので、参考にしてみてください。

 また、OSに標準搭載されているカメラアプリもGitHub上で公開されています。こちらは少し読むのが難しいですが、Camera APIを余すところなく利用していますので、非常に参考になると思います。

次のページ
アプリの申請フローについて

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Firefox OS搭載スマホ「Fx0」でつくろう! はじめてのFirefox OSアプリ開発連載記事一覧

もっと読む

この記事の著者

鈴木 和幸(スズキ カズユキ)

 1991年岐阜生まれ。株式会社リクルートホールディングス メディアテクノロジーラボ(MTL)所属。社内スタートアップでリーンな顧客開発・製品開発を実践中。現在はエンジニア向けメディアPOSTDを運営。個人でもAndroid版Firefoxのローカライズなどの活動に従事。 Twitter:@kechol Web:kechol.net

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

【AD】本記事の内容は記事掲載開始時点のものです 企画・制作 株式会社翔泳社

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/8532 2015/03/13 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング