かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

Xamarin.Formsで笑顔測定をしよう(AndroidとUWP)

最近笑顔してますか?こんな感じの笑顔測定アプリを作ってみようと思います。これならボッチでも笑顔の練習できるよ!

左がニュートラルな顔、右が笑顔の場合です!スコアが変わってますね。

f:id:okazuki:20161121163608p:plain

ということで、Cognitive ServiceのFace APIを使って笑顔判定するものをXamarin.Formsで作ってみようと思います。 プロジェクトテンプレートは安定のPrism Tmeplate Packで作ります。 これだとおぜん立てとかがあって楽なので。

ということで、今回のお題を達成するにはカメラで写真を撮るということとCognitive ServiceのAPIを呼び出すという2つの段階を踏まないといけません。順番に見ていきましょう。

カメラにアクセスする

Xamarinには、Pluginという便利なクロスプラットフォームで各種プラットフォーム固有の機能にアクセスするためのライブラリがあったりします。 カメラもPluginがあったりします。

github.com

ということで、NuGetでXam.Plugin.Mediaをインストールしましょう。 するとreadme.txtが表示されます。

そこに書いてある通りに、以下の属性の追加とMainActivityのメソッドのオーバーライドを行います。

[assembly: UsesFeature("android.hardware.camera", Required = false)]
[assembly: UsesFeature("android.hardware.camera.autofocus", Required = false)]
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
    PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}

UWPは、Webカメラの機能にマニフェストでチェックを入れておきます。

カメラの下準備が整ったら以下のような初期化コードをApp.xaml.csに追加します。

Plugin.Media.CrossMedia.Current.Initialize();

これで下準備は完了です。 以下のようなコードで画像を取得してImageSource(画像のもと)を生成できます。

var file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
{
    DefaultCamera = Plugin.Media.Abstractions.CameraDevice.Front,
    AllowCropping = false,
});
if (file == null) { return; }

this.ImageSource = ImageSource.FromStream(() => file.GetStream());

Cognitive Serviceの呼び出し

次にCongnitive Serviceの呼び出しです。 Azureポータルから、Face APIとかで検索するとCongnitive Serviceが作成できるのでFace APIを選んでFreeプランあたりで作成しておきましょう。

ポータルのKeyからアクセスに必要になるキーを取得します。

f:id:okazuki:20161121155113p:plain

キーを取得したら、NuGetからMicrosoft.ProjectOxford.Faceをインストールしましょう。OxfordというのはCongnitive Serviceのプレビュー時代の名前になります。

Face APIの呼び出し自体は簡単で、返して欲しい属性(今回の場合は笑顔判定なのでスマイル)を指定してDetectAsyncを呼び出すだけです。クライアントの生成時に先ほど取得したキーを指定するのを忘れずに。

var client = new FaceServiceClient("ここにキーを設定する");
var result = await client.DetectAsync(file.GetStream(), returnFaceAttributes: new[]
{
    FaceAttributeType.Smile,
});

if (!result.Any()) { return; }

await this.PageDialogService.DisplayAlertAsync("Smile point", $"Your smile point is {result.First().FaceAttributes.Smile * 100}", "OK");

実行結果

UWPとAndroidしか持ってないのでiOSは試せてない(iOSはiOSでプラグインの設定が必要そう)のですがばっちり動きました。

Android

f:id:okazuki:20161121163922j:plain

UWP

f:id:okazuki:20161121163949p:plain

まとめ

ということでXamarinとMediaのPluginとCongnitive Serviceを使って簡単笑顔測定アプリが出来ました。 Xamarin.Formsで作ったからUWPでもAndroidでも動くので素敵ですね。

ということで、ソースコードは以下にあげています。

github.com

Xamarinはいいぞ。