技術顧問の増田です。
少し間が空いてしまいましたが、Xamarin.Android の続きのお話をしましょう。いままでは、Xamarin を使ってスマートフォンの一般的な機能(画面出力やWeb APIなど)を使ってきましたが、今回からは少し Android 特有の機能を使っていきます。いわゆる、エミュレーターではなくて実機を使ったプログラミングが必要なところです。
最初は、Android のカメラ機能を利用してみましょう。サンプルコードは https://github.com/moonmile/sg-xamarin-sample の sgCamera フォルダーにあります。
バックナンバー
- 第1回 C#で自作Android アプリを作ろう:出帆準備編
- 第2回 C#で自作Android アプリを作ろう:試験運用編
- 第3回 C#で自作Android アプリを作ろう:時計アプリを作る
- 第4回 C#で自作Android アプリを作ろう:RSSを取得してリスト表示
- 第5回 C#で自作Android アプリを作ろう:Web APIで路線情報を表示
- 第6回 C#で自作Android アプリを作ろう:Twitter APIでファボリストを取得
- 第7回 C#で自作Android アプリを作ろう:簡易アンケートを作ろう
- 第8回 C#で自作Android アプリを作ろう:カメラ機能を使おう
スマホでカメラを使う
スマートフォンのカメラの扱い方は、それぞれのスマートフォン(Android/iOS/Windows)によって異なるので、共通プラットフォーム(Xamarin.Forms)を使うのではなく、個別のコードを書くことになります。共通コードを書くことも不可能ではないのだけど、カスタムレンダラを使ったり画面遷移がOSごとに異なっていたり保存先のフォルダが云々という差があるので、個別で使うのであれば個別に作ってしまったほうが手っ取り早いってことなんですけどね。一応、Xamarin.Media を使うとできるようなことも書いてあるのですが、今回は、以下のサンプルを使って Xamarin.Android で作っていきましょう。
Take a Picture and Save Using Camera App – Xamarin
https://developer.xamarin.com/recipes/android/other_ux/camera_intent/take_a_picture_and_save_using_camera_app/
Android のカメラ機能を使うと、
- 撮影を開始する。
- 撮影する。
- 撮影した画像をファイルに保存する。
- プレビューのために保存したファイルを表示する。
という3手順が必要になります。実は、3のファイルに保存しない方法もあるのですが、解像度が小さい(160ドットぐらいしかない)ので使い物になりません。このため、Android では、Intent クラスを使って別のアクティビティを起動させます。ちょうどプログラム間の連携機能のようなものです。
撮影を開始する
自前のカメラアプリを作って撮影開始の「OPEN CAMERA」ボタンをタップしたときの処理を作ります。
1 2 3 4 5 6 7 |
private void Btn_Click(object sender, EventArgs e) { Intent intent = new Intent(MediaStore.ActionImageCapture); // ① _file = new File(_dir, String.Format("myPhoto_{0}.jpg", Guid.NewGuid())); // ② intent.PutExtra(MediaStore.ExtraOutput, Android.Net.Uri.FromFile(_file)); // ③ StartActivityForResult(intent, 0); // ④ } |
- カメラ機能を呼び出すための MediaStore.ActionImageCapture でインテントを作成します。
- カメラで撮影したときのファイル名を作成しておきます。
- 起動するアクティビティ(ここではカメラ機能)にファイル名を渡します。
- アクティビティを起動します。ここではカメラ機能からの戻り値を取るために、StartActivityForResultメソッドを使っています。
ファイルに保存する
起動したカメラ機能で撮影をした後に、チェックボタンをタップして確定させるとファイルに保存されます。
ファイルに保存されると、OnActivityResult イベントが発生します。
保存した画像を表示する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) { base.OnActivityResult(requestCode, resultCode, data); // Make it available in the gallery Intent mediaScanIntent = new Intent(Intent.ActionMediaScannerScanFile); // ① var contentUri = Android.Net.Uri.FromFile(_file); // ② mediaScanIntent.SetData(contentUri); SendBroadcast(mediaScanIntent); // Display in ImageView. We will resize the bitmap to fit the display. // Loading the full sized image will consume to much memory // and cause the application to crash. int height = Resources.DisplayMetrics.HeightPixels; int width = image1.Width; bitmap = _file.Path.LoadAndResizeBitmap(width, height, text1); // ③ if (bitmap != null) { image1.SetImageBitmap(bitmap); // ④ bitmap = null; } // Dispose of the Java side bitmap. GC.Collect(); } |
- 保存したファイルを読み出すために Intent.ActionMediaScannerScanFile でインテントを作成します。
- ファイル名を指定して、ブロードキャストで通知します。Android の Gallay アプリに見えるようにするための処理です。
- 保存した画像ファイルをロードします。LoadAndResizeBitmap メソッドは、縦横のサイズをスマホの画面に合わせるための自作関数です。
- 取得した Android.Graphics.Bitmap オブジェクトを SetImageBitmap メソッドを使って画面に表示させます。
動作させると、こんな感じで撮影した画像が表示されるようになります。カメラ機能はエミュレーターを使っても動作させることが可能です。
実際の Android スマートフォンの場合は背面と前面のカメラがあるので、切り替えて撮影してみてください。画像のサイズが違うことがわかります。
まとめ
これで Xamarin.Android を使ってカメラ撮影できることが分かりました。画像ファイルは Android.Graphics.Bitmap で読み込めるので、これを加工してサーバーに送るツールができそうですね。次回は、撮影した画像を加工する部分を作ってみましょう。
次回もお楽しみに。