Xamarin 日本語情報

Xamarin(ザマリン) の代理店だったエクセルソフト田淵のブログです。主に Xamarin に関するエントリーをアップしていきます。(なるべく正しい有益な情報を掲載していきたいと考えていますが、このブログのエントリーは所属組織の公式見解ではありませんのでご注意ください)

目次

はじめに

Xamarin (ザマリンと読みます) とは、Gnome, Mono の開発者である Migel de Icaza (ミゲル・デ・イカザ) 氏が立ち上げた企業名であり、C#Android, iOS, Mac のネイティブアプリを作成できる開発ツール郡 (Xamarin.Android*1、Xamarin.iOS*2、Xamarin.Mac*3、Xamarin Studio*4 など) のブランド名です。

2016/4/1 をもって、Visual Studio に付いてくるようになりました。

本ブログは、エクセルソフトの田淵義人が Xamarin に関する様々な情報を記載しています。Xamarin って何だろ?という方、Xamarin についてもっと知りたい。というような開発者の皆様の手助けになれば幸いです。

 

Visual Studio 2017 で Xamarin を使うエントリー書きました。

ytabuchi.hatenablog.com

 

Xamarin とは?

紹介スライド、エントリーなどをご覧ください。

 

qiita.com

書籍

 

コミュニティ

公式コミュニティサイト Japan Xamarin User Group (JXUG) 

facebook User Group

 

各種情報へのリンク

本ブログの主なエントリー

全般
Xamarin.Forms
Xamarin.iOS、Xamarin.Android 記事
Xamarin.Forms TIPS/逆引き
Xamarin.Forms Plugins/ライブラリ
Xamarin.Forms MVVM
Xamarin Test Cloud/Unit Test
BAD KNOW HOW

全記事一覧 - Xamarin 日本語情報

Xamarin.Forms エントリー纏め

 

事例

事例

 

エクセルソフト Xamarin ページ

Qiita

ブログ、連載記事など

 Xamarin 本家の開発者向けの情報(英語)

Xamarin 学習用リソースまとめ でも公式情報を纏めていますので、ご参照ください。

 

Xamarin 気になった方は

是非 ダウンロード(直接) / ダウンロード(弊社経由) して触ってみてください。
学習用リソースJXUG リンクページ に参考資料を纏めてますので併せてどうぞ。

Xamarin の情報が欲しい方はこのブログも購読いただいたりすると嬉しいです。

以上です。

*1:旧 MonoDroid, Mono for Android

*2:旧 MonoTouch

*3:OSS版はMonoMac

*4:OSS 版は MonoDevelop

Xamarin で Microsoft Cognitive Services を使うには - その2

こんにちは。エクセルソフトの田淵です。

この記事は Cogbot Advent Calendar 2018 の 22日目のエントリーです。遅れてしまい、すみません!

先日は Xamarin で Microsoft Cognitive Services を使うには - その1 として、Cognitive ServicesVision(視覚) を使ってみました。

今日は Language(言語)を使ってみます。

サンプルは以下にアップしてあります。

github.com

Cognitive Services - Language(言語)

Language の中にもいくつかサービスがあります。

azure.microsoft.com

アプリとサービスが構造化されていないテキストの意味を解釈したり、話者の発言の裏にある意味を認識したりできる言語サービスについて、詳細をご覧ください。

とのこと。これも非常に AI っぽいサービスですね。

Translator Text

文章の翻訳をしてくれるサービスです。

60以上の言語をサポートしていて、注目すべきは入力された文章の言語を自動判別できることだと思います。

対応言語は以下をご参照ください。

docs.microsoft.com

サービス作成

「Translator」で検索して、「Translator Text」を F0 の価格プランで作成しましょう。Translator Text は Global なのでリージョンの指定はありません。

余談ですが、いくつかのドキュメントに Cognitive Services の All-in-One キーを使う。というような記述があるのですが、@BEACH_SIDE さんがいくつかのサービスでは All-In-One キーはなぜか使えないって言っていたので、なるべくそれぞれのサービスのキーを作成して使っていきたいと思います。

beachside.hatenablog.com

ドキュメント

以下のサンプルを元に実装していきましょう。

docs.microsoft.com

NuGet パッケージとコード

NuGet パッケージマネージャーで、恐らく一番上に表示されている「Newtonsoft.Json」をインストールします。

(カンの良い方は気づいたはず。そう。SDK がありませんでしたw)

コードの説明

HttpClient で普通にアクセスして JSON をデシリアライズするだけなので難しいところはないかと思います。いくつかポイントを解説します。

To の言語

RequestUri にエンドポイント https://api.cognitive.microsofttranslator.com/translate?api-version=3.0&to=de&to=it と渡すと、to= の部分に翻訳してくれます。

今回は英語と日本語だけなので、EnumToLanguage を用意して、TranslateTextAsync の引数に渡すようにしました。

public enum ToLanguage
{
    en,
    ja
}
JsonConvert.DeserializeObject<T> の型

レスポンスのサンプル にもありますが、以下のような JSON が返ってきます。

[
  {
    "detectedLanguage": {
      "language": "en",
      "score": 1.0
    },
    "translations": [
      {
        "text": "Hallo Welt!",
        "to": "de"
      },
      {
        "text": "Salve, mondo!",
        "to": "it"
      }
    ]
  }
]

一番外側が [] になっているので、以下の TranslatedObject の List でデシリアライズします。

JsonConvert.DeserializeObject<List<TranslatedObject>>(jsonResponse)

です。

JsonProperty

アッパーキャメルでプロパティを設定しなおしています。

public class DetectedLanguage
{
    [JsonProperty("language")]
    public string Language { get; set; }
    [JsonProperty("score")]
    public double Score { get; set; }
}

public class Translation
{
    [JsonProperty("text")]
    public string Text { get; set; }
    [JsonProperty("to")]
    public string To { get; set; }
}

public class TranslatedObject
{
    [JsonProperty("detectedLanguage")]
    public DetectedLanguage DetectedLanguage { get; set; }
    [JsonProperty("translations")]
    public List<Translation> Translations { get; set; }
}

f:id:ytabuchi:20181225183805p:plain:w300

良いですね!

コードの説明

Text Analytics

いくつかサービスがありますが、今回は「テキストの感情分析」を使ってみます。

以下のデモをみてみましょう。文章の感情を読み取り、ポジティブなのかネガティブなのかを返します。

azure.microsoft.com

2018年12月時点では、残念ながら日本語はキーワード抽出しか対応していません。

docs.microsoft.com

そのため、上記の TranslatorText と組み合わせて英語に翻訳してから Sentiment(感情)を分析してみたいと思います。

サービス作成

「Text Analytics」または「テキスト分析」で検索して、「テキスト分析」を F0 の価格プランで作成しましょう。どのリージョンに作ったか?を覚えておいてください。

f:id:ytabuchi:20181225184041p:plain:w600

ドキュメント

以下のサンプルを元に実装していきましょう。

docs.microsoft.com

NuGet パッケージとコード

NuGet パッケージマネージャーで、Windows の場合は「プレリリースを含める」、macOS の場合は「プレリリースパッケージを表示する」のチェックボックスをオンにして、「Microsoft.Azure.CognitiveServices.Language.TextAnalytics」を検索してインストールします。2018年12月時点の SDK のバージョンは 2.8.0-preview です。

2018/12/20 時点では、インストールする Microsoft.Azure.CognitiveServices.Language.TextAnalytics の 2.8.0-preview の依存パッケージである Microsoft.Rest.ClientRuntime の 2.3.17 に以下のバグがあるようで、「Darwin17.7.0DarwinKernelVersion17.7.0FriNov2204316PDT2018rootxnu-4570.71.171/RELEASE_X86_64' is invalid.」というエラーが出てました。個別に Microsoft.Rest.ClientRuntime の最新版 2.3.18 をインストールすることで回避可能です。

github.com

f:id:ytabuchi:20181225185521p:plain:w450

DetectLanguageAsync

テキスト分析を行う前に、TextAnalyticsClientDetectLanguageAsync メソッドで認識した言語が英語かどうかを判定しています。

第一引数の BatchInput は引数 IList<Input> をとり、Input の引数は [string id = null], [string text = null] なので、

new Input(null, text)

を指定すると正しい結果が取れないようでした。そのため、ID を new Input("0", text), と指定してあげる必要があるようです。

戻り値の DetectedLanguages には NameIso6391Name がありますので、今回は Iso6391Name"en" を取得できれば OK ということにしました。

言語検出の詳細は以下をご参照ください。

docs.microsoft.com

SentimentAsync

英語であることを確認したら、TextAnalyticsClientSentimentAsync メソッドで感情を分析します。

こちらも、DetectLanguageAsync と同様に、第一引数の MultiLanguageBatchInput は引数 IList<MultiLanguageInput> をとり、MultiLanguageInput の引数は [string language = null], [string id = null], [string text = null] なのですが、new MultiLanguageInput("en", "0", text) と ID を指定してあげます。

あとは戻り値の Documents[0].Score をみてあげれば結果が取得できます。

f:id:ytabuchi:20181225193030p:plain:w300

うん、こちらも良い感じ。

.NET Core のコンソール

今回も同様に、まずはコンソールアプリで確認してみましょう。

Console.WriteLine("Cognitive Services - Language - Translator Text");

var ja = "今日は人生で一番良い日です。";
var en = "I had a wonderful trip to Seattle and enjoyed seeing the Space Needle!";

var translationClient = new TranslatorTextService();
var ja2en = translationClient.TranslateTextAsync(ja, TranslatorTextService.ToLanguage.en).Result;
var en2ja = translationClient.TranslateTextAsync(en, TranslatorTextService.ToLanguage.ja).Result;

Console.WriteLine($"Source: {ja}\n" +
    $"Translated: {ja2en}");
Console.WriteLine($"Source: {en}\n" +
    $"Translated: {en2ja}");


Console.WriteLine("Cognitive Services - Language - Text Analytics");

var textAnalysisClient = new TextAnalyticsService();
var sentiment1 = textAnalysisClient.AnalyzeSentimentAsync(en).Result;
var sentiment2 = textAnalysisClient.AnalyzeSentimentAsync(ja2en).Result;

Console.WriteLine($"Source: {en}\n" +
    $"Sentiment(Happiness): {sentiment1*100:00}%");
Console.WriteLine($"Source: {ja2en}\n" +
    $"Sentiment(Happiness): {sentiment2*100:00}%");

問題なさそうです!

Xamarin.Forms の実装

こちらも最後は Xamarin.Forms の実装です。今回からページを複数使うので、TabbedPage を使用しました。

TabbedPage
<?xml version="1.0" encoding="UTF-8"?>
<TabbedPage
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:XFCognitiveServices"
    xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
    ios:Page.UseSafeArea="true"
    xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
    BarBackgroundColor="#F1F1F1"
    android:TabbedPage.ToolbarPlacement="Bottom"
    android:TabbedPage.BarItemColor="#999999"
    android:TabbedPage.BarSelectedItemColor="#303F9F"
    x:Class="XFCognitiveServices.MainTabPage">
    <TabbedPage.Children>
        <local:VisionPage Title="Vision"
                          Icon="vision.png"/>
        <local:LanguagePage Title="Language"
                            Icon="language.png"/>
  </TabbedPage.Children>
</TabbedPage>

各ページ内で別のページを呼び出すこと(Navigation.PushAsync(new SomePage()))がある場合は、<local:VisionPage/> の代わりに、以下のように NavigationPage で包んで表示してください。

<NavigationPage Title="Vision"
                Icon="vision.png">
    <x:Arguments>
        <local:VisionPage />
    </x:Arguments>
</NavigationPage>

Tabbed Page の詳細は以下です。

docs.microsoft.com

Android で Bottom Tab を使う

Xamarin.Forms 3.1 以降では、Android に Bottom Tab を使用できるようになりました。

上記 TabbedPage の以下のオプションの部分です。

xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
BarBackgroundColor="#F1F1F1"
android:TabbedPage.ToolbarPlacement="Bottom"
android:TabbedPage.BarItemColor="#999999"
android:TabbedPage.BarSelectedItemColor="#303F9F"

docs.microsoft.com

Bottom Tab は @Santea3173 くんXamarin Advent Calendar 2018 の 18日目の 最近の Xamarin.Forms のアップデートを試してみる で触れてますね。非常に良いです。

TabbedPage のアイコン

Android でも Bottom Tab を使うことで、iOSAndroid 両方にアイコンが必要になります。色は上書きされますので、表示したい部分「以外」を透過に設定した画像を用意します。

iOS はアイコンのファイル名に倍率を付ける必要があります。@1x30x30@2x60x60@3x90x90 のサイズで用意してプロジェクトの Resource フォルダに追加して、ビルドアクションを BundleResource にしておけば表示されます。

f:id:ytabuchi:20181225175051p:plain:w300

AndroidAndroid プロジェクトの Resources/drawable フォルダにファイルを追加して、ビルドアクションを AndroidResource にしておけば表示されます。サイズはいい感じにしてくれるので(多分)問いません。(私は 120x120 のファイルを追加しました。)

f:id:ytabuchi:20181225174507p:plain:w300

ちなみに、Android の Bottom Tab では、4個以上から非選択タブのテキストが隠れていい感じに表示してくれるようになります。便利w (iOS はそのままでした。)

f:id:ytabuchi:20181225180036p:plain:w450

f:id:ytabuchi:20181225180050p:plain:w450

UseSafeArea

iPhone X のノッチ用の設定です。以下を各ページの XAML に付けます。

xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
ios:Page.UseSafeArea="true"

以下のドキュメントにもありますが、注意点として Page.Padding を強制的に上書きするだけなので、他で設定している場合は注意してください。とのことです。

docs.microsoft.com

IsSwipePagingEnabled

AndroidTabbedPage でスワイプで各タブページを遷移できるオプションです。が、なんか、標準でオンになっているっぽくて設定しなくてもスワイプできましたw

android:TabbedPage.OffscreenPageLimit="2"
android:TabbedPage.IsSwipePagingEnabled="true"

一応ドキュメントへのリンクです。

docs.microsoft.com

まとめ

今日は 言語 Language のサービスをいくつか使ってみました。

入力した言語を自動認識するというのに驚きました。こちらも簡単に翻訳機能をアプリに追加できるので魅力的ですね。

サンプルは以下にアップしてあります。興味があればビルドしてみてください。

github.com

チャットアプリとかはみんな使えばいいのに!と思いましたが、ローカルにエンジンが無いと無限にお金が掛かってしまうかw

今後も触っていって、「そのXX」まで書いていきたいです。

Xamarin 気になった方は

Visual Studio 2017 をインストールして触ってみてください。手順書は こちらのエントリー をご覧ください。 学習用リソースJXUG リンクページ に参考資料を纏めてますので併せてどうぞ。

Xamarin の導入支援サービスを始めました。ベースは基本的なアプリを一緒に作ることで Xamarin を使えるようになって頂く内容ですが、ご要望に応じて講習内容のカスタマイズも可能です。詳しくは田淵までお問い合わせください(^^)

Xamarin 有償トレーニング : XLsoft エクセルソフト

Xamarin の情報が欲しい方はこのブログも購読いただいたり、私のTwitterアカウントをフォローいただいたりすると嬉しいです。

私が所属している エクセルソフト の宣伝を少しさせてください。弊社は開発者向けの様々なソフトウェアを扱っています。Office/PDF ファイルを .NET/Java で操作するライブラリ Aspose(アスポーズ)Windows アプリ、Web ページ、iOS/Android アプリの UI テストができる TestComplete などお勧めです(^^) また、Visual Studio Professional/Enterprise with MSDN も販売してますし、日本で売っていない海外のソフトウェア、開発ツールなどを弊社経由で日本円で購入頂くことも可能です。ご興味あれば 弊社ページ を覗いてみてください。

以上です。

Xamarin で Microsoft Cognitive Services を使うには - その1

こんにちは。エクセルソフトの田淵です。

Cogbot Advent Calendar 2018 - Qiita の 21日目のエントリーです。

qiita.com

明日もこのエントリーの続きでその2として書きたいと思います。

サンプルプロジェクトは以下に置いておきます。興味があれば見てみてください。

github.com

経緯

先日、Xamarin Advent Calendar 2018 - Qiita の 2日目の記事として、AWS Rekognition を使って顔認識を使うエントリーを書きました。

ytabuchi.hatenablog.com

上記記事の経緯は、先日の「初心者向けXamarinハンズオン! #5」Microsoft Cognitive Services の Face を使ったアプリ を作ってドキュメントをアップデートしたので、同じことを AWS でやったらどんな感じかな?というものでした。せっかく Face をやったので、その他の沢山のサービスも使ってみたいな。ということで、面白そうだったり、C#SDK があるサービスを色々触ってみることにします。

Cognitive Services を C#SDK で使う時の書き方ってこんな感じか。という入口にしてもらえると嬉しいです。

2018/12/20 時点での情報です。Cognitive Services は結構早いペースでサービスの統廃合や名称が変わったりするのでご注意ください。

Congnitive Services を使うための準備

大前提として、使うにはどうすれば良いか?という点ですが、Cognitive Services の各種ページで「〜を試す」って青いボタンをクリックすると以下の画像が出てきます。

f:id:ytabuchi:20181221115854p:plain:w600

  • 既存の Azure アカウント
  • 無料の Azure アカウント(評価アカウント)
  • ゲスト

で使えます。クレジットカードの登録は必要ですが無断で課金されることはないので、アカウントをお持ちでない方は無料の Azure アカウントを作っておくと良いでしょう。

IaaS には無料のプランはないのですが、例えば Web Apps のような PaaS の各種サービスであれば大体無料プランが用意されているので、ちょっと試したい。という時に便利です🙆🏻‍♂️

Azure のアカウントで Azure Portal にログインして、Cognitive Services 向けのリソースグループを作っておきましょう。このエントリーでは「Cognitive Services」というリソースグループを東南アジアに作成して Cognitive のサービスを纏めています。

f:id:ytabuchi:20181221131341p:plain:w600

各種サービスを作成するときに、「Resource Group」の欄から作成済みのリソースグループを選択してください。

f:id:ytabuchi:20181221132003p:plain:w300

余談ですが、Cognitive Services の各種サービスを作成すると、インスタンスが起動する訳ではなく、アクセスするためのキーを生成しているだけのようです。そのため、このエントリーでは各種サービス名を「〜Key」という名前にしています。

Xamarin で使う前準備

Xamarin.Forms で作っていきますので、Xamarin.Forms がビルドできる環境をご用意ください。

2018年12月現在の Visual Studio 2017 または Visual Studio for Mac の最新版を使っています。

使用する SDK .NET Standard 対応のものが多いので、

  1. 空のソリューションを作成
  2. .NET Standard 2.0 のライブラリプロジェクトを作成
  3. 確認用に .NET Core 2.1 のコンソールプロジェクトを作成
  4. 最後に Xamarin.Forms のプロジェクトを作成

という流れで、以下の構成にしました。各種 Cognitive Services を使う 〜Service クラスをそれぞれ用意している感じです。

f:id:ytabuchi:20181221133854p:plain:w450

動作を確認するたびにスマホでチェックするのも大変なので、ライブラリのコードを書いてコンソールで確認し、動作を確認してから最後に Xamarin.Forms の UI を書く。という流れでやっています。

それではいきましょう!

Cognitive Services とは

azure.microsoft.com

f:id:ytabuchi:20181214162638p:plain:w600

色々な方が解説しているので説明は省きますが、Azure の PaaS を使って AI でなんかした結果を返してくれるサービスです。(雑)

今日のその1 のエントリーは、視覚についてです。

Cognitive Services - Vision(視覚)

視覚の中にはいくつかのサービスがあります。

azure.microsoft.com

視覚サービスによりアプリとサービスがどのように画像やビデオのコンテンツを正確に識別および分析できるようになるかをご覧ください。どのサービスも無料でお試しいただけます。また、次の機能を備え、コンピューター ビジョンに対応したアプリとサービスをすばやく作成できます。

とのこと。AI と言えば!という感じのサービスですよね。

Computer Vision

主に画像解析を行います。

  • 画像の分類
  • 画像内のシーンおよびアクティビティ認識
  • 画像内の有名人とランドマークの認識
  • 画像内の光学式文字認識 (OCR)
  • 手書き認識

この中で、「画像内のシーンおよびアクティビティ認識」と「画像内の光学式文字認識 (OCR)」をやってみましょう。

Computer Vision - 画像内のシーンおよびアクティビティ認識

どんなことをしてくれて、どんなデータが返ってくるか?は以下のデモページの「画像の分析」を見てみてください。

azure.microsoft.com

例えば上記のデフォルトで選択されている電車とホームの画像は、特徴名と値で、「説明」の中に「captions」があり、その「text」が「people waiting at a train station」となっています。画像のアクティビティを認識してくれる。ということですね。

今回は caption の部分を SDK で取得します。

サービス作成

まずはサービスを作成しましょう。

リソース作成のブレードで「Computer Vision」を検索して作成します。

f:id:ytabuchi:20181221133120p:plain:w600

私は以下の設定で作成しました。今後も大体こんな感じで作成していくので、この後の作成時の説明は割愛します。

  • 名前:ComputerVisionKey
  • 場所:東南アジア
  • 価格レベル:F0
  • Resource Group:「Cognitive Services」

作成が終わったらリソースに移動し、Key メニューをクリックすると表示される Key を控えておきましょう。

f:id:ytabuchi:20181221140237p:plain:w600

ドキュメント

Computer Vision のページを開くと、赤枠のあたりに「ドキュメント」と「API」のリンクがあります。

f:id:ytabuchi:20181221134857p:plain:w600

大体どのサービスも同じサイト構成になっていますので、ドキュメントと API を見ながら開発を進めていきます。

画像内のシーンおよびアクティビティ認識は以下のサンプルを元に作っていきましょう。

docs.microsoft.com

当然ですが、API ドキュメント にあるように全て REST API として設計されているため、C# からであれば REST API のエンドポイントを HttpClient で叩けばすむ話なのですが、SDK でラップしてくれているので開発を楽に進められるようになるよ。ということですね。

NuGet パッケージとコード

NuGet から SDK .NET Standard ライブラリプロジェクトに追加します。NuGet パッケージマネージャーで、

Microsoft.Azure.CognitiveServices.Vision.ComputerVision」

を検索してインストールします。2018年12月時点の SDK のバージョンは 3.3.0 です。

詳細はサンプルコードを見てもらうとして、いくつかポイントを説明します。

VisualFeatureTypes

VisualFeatureTypes Enum は取得する情報を指定します。List で用意しておきます。

// 取得する属性を指定
private static readonly List<VisualFeatureTypes> features =
    new List<VisualFeatureTypes>()
{
    VisualFeatureTypes.Categories,
    VisualFeatureTypes.Description,
    VisualFeatureTypes.Tags
};
ComputerVisionClient とエンドポイント

ComputerVisionClient の引数に ApiKeyServiceClientCredentials("KEY") を渡してインスタンス化しています。2018年12月現在公開されている各種 SDK はこの形で Clinet をインスタンス化することが多いようです。

var computerVisionClient = new ComputerVisionClient(new ApiKeyServiceClientCredentials("<ENTER_KEY_HERE>")){ Endpoint = "<ENDPOINT_URI>"};

エンドポイントの URL はサービスを作ったリージョンによって異なりますので、ご注意ください。以下、API ドキュメントから引用します。

AnalyzeImageAsync メソッドと AnalyzeImageInStreamAsync メソッドの language 引数

API リファレンス によると、language パラメーターで英語、ポルトガル語、日本語、簡体中国語に対応しているような記述がありますので、

AnalyzeImageInStreamAsync(imageStream, visualFeatures, details, "ja") と日本語を指定するとちゃんと日本語で結果を返してくれます。

ImageAnalysis クラス

以下のように色々な情報が含まれています。

f:id:ytabuchi:20181221143011p:plain:w450

ただ今回は Caption だけを取得するので、GetCaption メソッドを用意して単純に analysis.Description.Captions[0].Text を返しています。

f:id:ytabuchi:20181221144931p:plain:w300

いい感じですね!

Computer Vision - 画像内の光学式文字認識 (OCR)

次は OCR です。先ほどのデモページ の「画像内のテキストの読み取り」を見てみてください。

OCR については説明不要かと思いますが、API ドキュメント によると Computer VisionOCR は以下の言語に対応しているようです。すごい!

サービス作成

画像認識と同じなので、先ほど作成した KEY を使用します。

ドキュメント

OCR は以下のサンプルを元に作成していきます。

docs.microsoft.com

NuGet パッケージとコード

同じ NuGet パッケージを使用します。

ComputerVisionClient とエンドポイント

別の OcrService クラスの ExtractLocalTextAsync メソッドを用意したので再度記述が必要ですが、中身は同じです。

RecognizePrintedTextInStreamAsync メソッドと OcrLanguages 引数

RecognizePrintedTextInStreamAsync メソッドの引数、1個目は detectOrientation で向きを自動認識してくれるので True が良いでしょう。2個目は画像の Stream で、3個目が言語です。

OcrLanguagesEnum で認識させたい各種言語を指定すれば良いのですが、指定なしで OcrLanguages.Unk(Unkown かな?)の自動認識になります。このままで日本語も認識してくれるので指定なしでも良いと思います。

日本語の表示は英語が混ざることが多いので、その場合はどちらかの認識を捨てなければいけません。

例えば以下のように確実に日本語だけの画像なら

f:id:ytabuchi:20181221154045p:plain:w300

ほぼ正確に読み取ってくれます。素晴らしいですよね!

f:id:ytabuchi:20181221154146p:plain:w300

が、例えば以下のような(こういうかなり小さい字でも読み取れます)日本語と英語が混じっている画像の場合は、英語部分が文字化けした日本語として読み取るか、英語部分のみを読み取るかのどちらかになってしまいます。

f:id:ytabuchi:20181221154225p:plain:w300

しっかりと読み取る場合には、2回言語設定を変えて読み取って比較してミックスする。などの処理が必要になるかもしれません。

OcrResult の処理

読み取り結果の OcrResult には読み取った区分ごとに Regions があり、その中に Lines があり、最後に Words があります。今回は取得したリージョンごとに Words を纏めてList<string> として返す GetAllText メソッドを用意しました。

Face

次は Face を触ってみましょう。以下がメインサイトです。

azure.microsoft.com

Face は以前の JXUG でやっているので、以下のドキュメントが参考になります。

github.com

サービス作成

「Face」で検索して、F0 の価格プランで作成しましょう。どのリージョンに作ったか?を覚えておいてください。

ドキュメント

以下のサンプルを元に実装していきましょう。

docs.microsoft.com

NuGet パッケージとコード

NuGet パッケージマネージャーで、Windows の場合は「プレリリースを含める」、macOS の場合は「プレリリースパッケージを表示する」のチェックボックスをオンにして、「Microsoft.Azure.CognitiveServices.Vision.Face」を検索してインストールします。2018年12月時点の SDK のバージョンは 2.2.0-preview です。

FaceClient

Endpoint は Computer Vision と同じく、作成したリージョンによって URL が変わるので注意してください。

今回は顔認識と感情読み取り機能を使用するだけなので、faceClientFaceDetectWith〜 のメソッドを使用していますが、Face 以外にも、FaceListPersonGroup などもあります。

それぞれの詳細は API ドキュメント を参照いただきたいのですが、Person Group では顔情報をグループに分けて登録し、学習させて、そのエンジンに対して顔認識の結果を確認する。などもできるようです。

Facebook の自動顔認識とかに近いイメージでしょうか。Qiita で試している方がいらっしゃったのでリンクを貼っておきます。

qiita.com

FaceAttributeType[] の設定

取得する情報を FaceAttributeType[] の配列に格納しておきます。

FaceAttributeTypeEnum が用意されていますので、必要な情報を追加してください。

f:id:ytabuchi:20181221172922p:plain:w300

DetectWithUrlAsyncDetectWithStreamAsync メソッド

URL で投げた画像を解析する DetectWithUrlAsync と、Stream を解析する DetectWithStreamAsync がありますが、基本的な使い方は同じです。

IList<DetectedFace> が返ってきますので、GetFaceEmotions メソッドを用意して、取得した年齢や性別などの情報を移し変えてます。

DetectedFace クラス

今回は学習も取得もしていませんが、顔を登録しておくと、FaceId が取得できます。また、写真のどの位置の顔なのか?は FaceRectangle で返ってきますので、例えば認識した顔に枠を着けてその上に年齢を表示する How-Old.net みたいなこともできますね。

f:id:ytabuchi:20181221175349p:plain:w600

自撮りだとこんな感じですね!(関係ないけど、私、最近すごい老けた気がしてる!w)

f:id:ytabuchi:20181221180026p:plain:w300

.NET Core のコンソール

ライブラリプロジェクトを参照して、コンソールでテストしてみましょう。

Console.WriteLine("Cognitive Services - Vision - Face - DetectFace");

var faceClient = new FaceService();
var faces = faceClient.GetRemoteEmotionsAsync(faceImage).Result;

Console.WriteLine($"Detected: {faces.Count} Person.");
foreach (var face in faces)
{
    Console.WriteLine($"Emotion Result:\n" +
        $"Age:{face.Age} Gender:{face.Gender} Happiness:{face.Happiness}%");
}


Console.WriteLine("Cognitive Services - Vision - ComputerVision - Image Analysis");

var analysisClient = new ImageAnalysisService();
var caption = analysisClient.AnalyzeRemoteImageAsync(meetupImage).Result;

Console.WriteLine($"Analysis Result:\n" +
    $"{caption}");


Console.WriteLine("Cognitive Services - Vision - ComputerVision - OCR");

var computerVisionClient = new OcrService();
var regions = computerVisionClient.ExtractRemoteTextAsync(ocrImage).Result;

Console.WriteLine($"Detedted: {regions.Count} Regions");
foreach (var region in regions)
{
    Console.WriteLine($"OCR Result:\n" +
        $"{region}");
}

こんな感じでデバッグも出来るので便利ですね!

Xamarin.Forms の実装

最後に Xamarin.Forms での実装です。写真を Media Plugin で撮ったり参照したりした後で、その写真を各サービスに投げています。コードの部分はそれこそ上記のコンソールとほぼ同じなので楽ですね。

github.com

Media Plugin で写真を撮る、または開くボタンの処理

private async void TakePictureButton_Clicked(object sender, EventArgs e)
{
    if (isPermissionGranted)
    {
        file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
        {
            Directory = "Sample",
            Name = "test.jpg",
            PhotoSize = PhotoSize.Medium
        });

        image.Source = ImageSource.FromFile(file.Path);
    }
    else
    {
        await DisplayAlert("Permissions Denied", "Unable to take photos.", "OK");
        //On iOS you may want to send your user to the settings screen.
        //CrossPermissions.Current.OpenAppSettings();
    }
}

private async void OpenPicureButton_Clicked(object sender, System.EventArgs e)
{
    if (isPermissionGranted)
    {
        file = await CrossMedia.Current.PickPhotoAsync();

        image.Source = ImageSource.FromFile(file.Path);
    }
    else
    {
        await DisplayAlert("Permissions Denied", "Unable to take photos.", "OK");
        //On iOS you may want to send your user to the settings screen.
        //CrossPermissions.Current.OpenAppSettings();
    }
}

各ボタンをクリックした時の処理です。ホントにほぼ同じw

private async void AnalyzeButton_Clicked(object sender, EventArgs e)
{
    var client = new ImageAnalysisService();
    var caption = await client.AnalyzeLocalImageAsync(file.Path);

    await DisplayAlert("Image Analysis", caption, "OK");
}

private async void OcrButton_Clicked(object sender, EventArgs e)
{
    var client = new OcrService();
    var regions = await client.ExtractLocalTextAsync(file.Path);

    var sb = new StringBuilder();
    sb.Append($"Extracted Regions: {regions.Count}\n\n");
    foreach (var region in regions)
    {
        sb.Append($"OCR Result:\n{region}\n");
    }

    await DisplayAlert("OCR", sb.ToString(), "OK");
}

private async void FaceButton_Clicked(object sender, EventArgs e)
{
    var client = new FaceService();
    var faces = await client.GetLocalEmotionAsync(file.Path);

    if (faces == null)
        await DisplayAlert("Error", "Can not detect", "OK");

    var sb = new StringBuilder();
    sb.Append($"Detected: {faces.Count}\n\n");
    foreach (var face in faces)
    {
        sb.Append($"Emotion Rsult:\nAge:{face.Age}\nGender:{face.Gender}\nHappiness:{face.Happiness}%\n");
    }

    await DisplayAlert("Face", sb.ToString(), "OK");
}

まとめ

今日は 視覚 Vision のサービスをいくつか使ってみました。

.NET Standard で書けるので、Xamarin からも他のアプリからも結構簡単に呼び出せて良いですね。試すだけなら無料でできるのも魅力です。

明日は 言語 Languages と検索 Search をやってみたいと思います。(終わるかな?w

明日ではなかったし、とりあえず言語だけですが、次のエントリーもアップしました。時間があれば、Search をやってみたいと思います。

ytabuchi.hatenablog.com

Xamarin 気になった方は

Visual Studio 2017 をインストールして触ってみてください。手順書は こちらのエントリー をご覧ください。 学習用リソースJXUG リンクページ に参考資料を纏めてますので併せてどうぞ。

Xamarin の導入支援サービスを始めました。ベースは基本的なアプリを一緒に作ることで Xamarin を使えるようになって頂く内容ですが、ご要望に応じて講習内容のカスタマイズも可能です。詳しくは田淵までお問い合わせください(^^)

Xamarin 有償トレーニング : XLsoft エクセルソフト

Xamarin の情報が欲しい方はこのブログも購読いただいたり、私のTwitterアカウントをフォローいただいたりすると嬉しいです。

私が所属している エクセルソフト の宣伝を少しさせてください。弊社は開発者向けの様々なソフトウェアを扱っています。Office/PDF ファイルを .NET/Java で操作するライブラリ Aspose(アスポーズ)Windows アプリ、Web ページ、iOS/Android アプリの UI テストができる TestComplete などお勧めです(^^) また、Visual Studio Professional/Enterprise with MSDN も販売してますし、日本で売っていない海外のソフトウェア、開発ツールなどを弊社経由で日本円で購入頂くことも可能です。ご興味あれば 弊社ページ を覗いてみてください。

以上です。

Xamarin で Amazon Rekognition を使うには

こんにちは。エクセルソフトの田淵です。

本エントリーは Xamarin Advent Calendar 2018 - Qiita の 2日目のエントリーです。明日は @gnk263 さんです。よろしくお願いいたします。

さて、先日「初心者向けXamarinハンズオン! #5」で最新の Face API を使って画像の人の幸福度を測定するところまでをやりました。(実は大本の Xamarin Dev Days は 2016 年に開催したイベントなのですが、ちゃんとプロジェクトやドキュメントが定期的にメンテされています。凄いですよね!)

jxug.connpass.com

ドキュメントは以下に公開しているので、興味のある方はぜひやってみてください。

github.com

で!アドベントカレンダーのネタとして Azure の Cognitive Service でもざっと触りなおそうかなーと思っていたのですが、@tonkun_no さんが「久しぶりに何か書きます(Xamarin + Cognitive Servicesかなぁ)」と仰っていたのでそこはお譲りし、違うやつ、AWS の顔認識の PaaS を触ってみることにしました。

完成するとこんな感じです。

f:id:ytabuchi:20181128173052p:plain:w300 f:id:ytabuchi:20181128173124p:plain:w300

Amazon Rekognition とは

ということで前段が長くなってしまいましたが、【Amazon Rekognition】人工知能・機械学習に基づく画像認識・画像解析サービス | AWS です。

Amazon Rekognition では、画像分析と動画分析をアプリケーションに簡単に追加できます。Rekognition API に画像または動画を与えるだけで、このサービスが対象物、人、テキスト、シーン、アクティビティ、それに不適切なコンテンツまで検出します。

とあるように、

  • 対象物体、シーン、アクティビティ検出(Computer Vision - 画像内のシーンおよびアクティビティ認識)
  • 顔認識(Face - 画像内の顔検出)
  • 顔分析(Face - 画像内の感情認識)
  • 動線の検出(Video Indexer - ビデオ内のオブジェクト、シーン、アクティビティの検出(かな?))
  • 安全でないコンテンツの検出(Content Moderator - 画像とビデオの性表現が露骨なコンテンツまたは不快感を与えるコンテンツのモデレート)
  • 有名人の認識(Computer Vision - 画像内の有名人とランドマークの認識)
  • 画像中のテキスト(Computer Vision - 画像内の光学式文字認識 (OCR)/手書き認識)

などが利用できます。(私は Microsoft Azure を良く使っているので、老婆心でカッコ内に Cognitive Services のディレクトリ | Microsoft Azure にある Azure Cognitive Services での同様のサービスを記載しましたw)

料金は こちら をご参照ください。

1年間の無料アカウントの方は「最初の 12 か月間は、1 か月あたり 5,000 枚の画像分析と、毎月最大 1,000 個の顔メタデータの保存が可能」で、一般アカウントでも、「1 か月あたり画像処理100 万枚までは処理画像 1,000 枚あたり 1.3 USD で顔メタデータのストレージは 1,000枚あたり 0.013 USD」です。

Xamarin からは .NET Standard 2.0 のライブラリで Rekognition にアクセスすれば良いでしょう。

早速やっていきます。

事前準備

いくつか必要なものがあります。

1)AWS アカウント

当然ですが、アカウントが必要です。新規に申し込むと1年間の無料利用権が付いていますので、今回のサンプルも無料で動かせます。まだアカウントを持っていない方は以下のドキュメントを参考にアカウントを作成してください。

AWS アカウント作成の流れ | AWS

2)IAM ユーザー

Root 権限を持つ上記のアカウントではなく、特定の権限のみをアタッチした IAM ユーザーでアクセスする必要があるようです。

ステップ 1: AWS アカウントを設定して IAM ユーザーを作成する - Amazon Rekognition

こちらに従って、任意の IAM ユーザーを作成してください。

私の場合は、コンソールにログインする Admin ユーザーと、今回使用する「プログラムによるアクセス」にだけチェックを付けた制限ユーザーを作成しました。

f:id:ytabuchi:20181128132421p:plain:w600

ユーザーを作成する時に一緒にグループも作成でき、グループに対してポリシーをアタッチできます。

f:id:ytabuchi:20181128133416p:plain:w600

「AmazonRekognitionFullAccess」をアタッチしたユーザーは以下のようになるはずです。

f:id:ytabuchi:20181128133451p:plain:w600

適切にユーザーを作成したら、「認証情報」タブで「アクセスキーの生成」をクリックします。

f:id:ytabuchi:20181128133532p:plain:w600

「アクセスキー ID」と「シークレットアクセスキー」を控えておきます。csv をダウンロードしても良いでしょう。

f:id:ytabuchi:20181128133728p:plain:w450

コンソールにログインできるようになれば、Rekognition Console からデモを試すことができますので、やってみてください。

3)AWSSDK for .NET のインストール

SDK があるようなので、インストールします。(必須ではありませんが、VS 拡張があるので入れておいた方が便利っぽいです。)

aws.amazon.com

.NET の「インストール」で最新の AWSSDK をダウンロードできます。

SDK には AWS Toolkit for Visual Studio が含まれているため、インストールすると、以下のように Visual Studio 2017 でプロジェクトテンプレートが使えたり、

f:id:ytabuchi:20181128141120p:plain:w450

アクセスキー ID とシークレットキーをプロファイル毎に登録できたりします。

f:id:ytabuchi:20181128141459p:plain:w600

準備は以上です。

(ユーザーの API Key と Secret Key だけあれば Azure みたいにインスタンスを作らなくても良い。というのは新鮮でした。)

NET Standard ライブラリ作成

準備ができたので .NET Standard のライブラリを作成します。私の場合は、「RekognitionSample.Core」という名前でプロジェクトを作成しました。

WindowsVisual Studio 2017 では「Visual C#>.NET Standard>クラスライブラリ」

f:id:ytabuchi:20181128134029p:plain:w450

macOSVisual Studio for Mac では「マルチプラットフォーム>ライブラリ>.NET Standard ライブラリ」で作成できます。

f:id:ytabuchi:20181128134347p:plain:w450

空のソリューションを最初に作成して、プロジェクトを追加するのが良いかもしれません。

AWS SDK Rekognition の NuGet パッケージを追加

Windows の場合は、Core プロジェクトを右クリックして、「NuGet パッケージの管理」をクリックし、表示される NuGet パッケージマネージャーで「awssdk.rekognition」と検索して、パッケージをインストールします。

f:id:ytabuchi:20181129092220p:plain:w450

macOS の場合は Core のプロジェクトを右クリックして、「追加>NeGetパッケージの追加」を選択し、表示されるパッケージマネージャーで「awssdk.rekognition」と検索して、パッケージをインストールします。

f:id:ytabuchi:20181128212622p:plain:w450

モデル追加

まずは解析した結果を受け取る DetectedFaceDetail モデルを用意します。

public class DetectedFaceDetail
{
    public string Gender { get; set; }
    public float GenderConfidence { get; set; }
    public float HappinessConfidence { get; set; }
    public int AgeRangeHigh { get; set; }
    public int AgeRangeLow { get; set; }
}

サービスクラス作成

次に、ファイルパスを引数にもらい、Rekognition の結果を DetectedFaceDetailList として返す RekognitionService クラスを作成し、メソッドを二つ用意します。

Rekognition は画像を渡す際に S3Bucket のタグから、または Base64エンコードした文字列を使用できます。SDK を利用すると、Base64エンコードする必要はなく、Amazon.Rekognition.Model.Image を渡すことができます。何と便利な!(ImageBytes プロパティは MemoryStream 型なので、それを受けて、内部で Base64 エンコードしてくれているのでしょう。)

public async Task<List<DetectedFaceDetail>> GetFaceDetailsFromLocalFileAsync(string filePath)
{
    //画像のMemoryStreamを作成
    var imageStream = await GenerateImageStreamFromLocalFileAsync(filePath);
    if (imageStream == null)
        return null;

    try
    {
        //AWS Rekognition Client を作成
        using (var rekognitionClient = new AmazonRekognitionClient(Secrets.AccessKey, 
                                                                    Secrets.SecretKey, 
                                                                    RegionEndpoint.APNortheast1))
        {
            var request = new DetectFacesRequest
            {
                Image = new Image
                {
                    Bytes = imageStream
                },
                Attributes = new List<string> { "ALL" }
            };

            //responseを受け取り、必要な情報を抽出
            var response = await rekognitionClient.DetectFacesAsync(request);

            var faceList = new List<DetectedFaceDetail>();
            foreach (var face in response.FaceDetails)
            {
                faceList.Add(new DetectedFaceDetail
                {
                    Gender = face.Gender.Value,
                    GenderConfidence = face.Gender.Confidence,
                    HappinessConfidence = face.Emotions.Find(x => x.Type.Value == EmotionName.HAPPY).Confidence,
                    AgeRangeHigh = face.AgeRange.High,
                    AgeRangeLow = face.AgeRange.Low
                });
            }

            return faceList;
        }
    }
    catch (Exception e)
    {
        Debug.WriteLine(e.Message);
    }

    return null;
}

private async Task<MemoryStream> GenerateImageStreamFromLocalFileAsync(string filePath)
{
    try
    {
        using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
        {
            using (var memoryStream = new MemoryStream())
            {
                await fileStream.CopyToAsync(memoryStream);

                return memoryStream;
            }
        }
    }
    catch (Exception e)
    {
        Debug.WriteLine(e.Message);
    }

    return null;
}

少し長いですが、

  • AmazonRekognitionClient(string, string, RegionEndpoint) を最初に控えておいた「アクセスキーID」「シークレットキー」とエンドポイントを指定してインスタンス化(エンドポイントは RegionEndpoint Class | AWS SDK for .NET V3 を参照してください。APNortheast1 が東京リージョンです。)
  • DetectFacesRequest クラスのインスタンスAmazon.Rekognition.Model.Image として画像の MemoryStream と取得する属性を指定
  • DetectFacesAsync メソッドでレスポンスを受け取り

をやっているだけです。

DetectFacesResponse オブジェクトが戻ってきますので、FaceDetails プロパティ内の List<Amazon.Rekognition.Model.FaceDetail> から必要な情報を取り出しています。

Amazon.Rekognition.Model.FaceDetail クラスの詳細は こちら をご覧ください。

FaceDetail に含まれる Emotions プロパティの型は List<Amazon.Rekognition.Model.Emotion> です。Emotion クラスには ConfidenceType があり、Type の型は EmotionName クラスField で定義されています。

各クラス、メソッドの詳細は API ドキュメントを参照してください。

AWS SDK for .NET V3 API Documentation

余談ですが、AWS SDK for .NET によるプログラミング - AWS SDK for .NET などのドキュメントは基本 .NET Framework クライアントアプリや ASP.NET MVC など向けに書かれていて、App.configWeb.config に設定を書き込み、コードから読み込ませる方法が紹介されています。

.NET Core を使用した AWS SDK for .NET の設定 - AWS SDK for .NET

上記のように .NET Core を使ったサンプルも紹介されているのですが、config ファイルの代わりに設定ファイルを読み込もう。という感じでした。

API ドキュメントに以下のような AmazonRekognitionClient() のコンストラクタで直接アクセスキー、シークレットキーを指定するやり方があったのでそれを使用していますが、ちゃんとやる場合は設定ファイルで指定するのが良いのかもしれません。

名前 説明
AmazonRekognitionClient(string, string, RegionEndpoint) Constructs AmazonRekognitionClient with AWS Access Key ID and AWS Secret Key

とりあえず、これで動くようになっているはずです。

Console アプリから確認

var rekognition = new RekognitionService();
var task = rekognition.GetFaceDetailsFromLocalFileAsync(@"D:\family.jpg");
var res = task.Result;

こんな感じで List<DetectedFaceDetail> が取得できるのがわかるかと思います。

Xamarin.Forms からの呼び出し

ここまでできれば、後は Xamarin.Forms から呼び出すだけです。

カメラで撮った写真を RekognitionService に渡してあげましょう。

カメラの写真の取得は、James Montemagno さんが作成した Xam.Plugin.Media を使います。

Xamarin.Forms のプロジェクト全部にプラグインをインストールします。

f:id:ytabuchi:20181128170324p:plain:w450

特に Android では Permission 関連でやることが多いので、ドキュメント をしっかり読んで対応しましょう。

Android でやらないといけない処理は

  • OnRequestPermissionsResultMainActivity に追加
  • CrossCurrentActivity のコードを MainActivityOnCreate 内に追加
  • AndroidManifest.xml<application></application> 内に provider の記述を追加
  • Resources フォルダ内に file_paths.xml ファイルを作成し、XML コードを追加

です。

Android で初回ビルド後の実行時に Java.Lang.Exception とかが出る場合は、Android プロジェクトの bin, obj フォルダを一度削除してリビルドするとうまくいくケースが多いです。

iOS でやらないといけない処理は

  • info.plist に Permission の処理を追加

です。

後は、MainPage.xaml を次のように書き換えて、

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
             ios:Page.UseSafeArea="true"
             xmlns:local="clr-namespace:RekognitionSample"
             x:Class="RekognitionSample.MainPage">
    <ScrollView>
        <StackLayout>
            <Button Text="Take a photo" 
                Clicked="Button_Clicked"/>
            <Image x:Name="image" Aspect="AspectFit"/>
        </StackLayout>
    </ScrollView>
</ContentPage>

小ネタとして iPhone X 対応の ios:Page.UseSafeArea="true" が入っています。

コードビハインドの Button_Clickedイベントハンドラに以下のコードを追加します。このコードは Xam.Plugin.Media のページの Permission Recommendations のコードをそのまま拝借したものです。

private async void Button_Clicked(object sender, EventArgs e)
{
    var cameraStatus = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Camera);
    var storageStatus = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Storage);

    if (cameraStatus != PermissionStatus.Granted || storageStatus != PermissionStatus.Granted)
    {
        var results = await CrossPermissions.Current.RequestPermissionsAsync(new[] { Permission.Camera, Permission.Storage });
        cameraStatus = results[Permission.Camera];
        storageStatus = results[Permission.Storage];
    }

    if (cameraStatus == PermissionStatus.Granted && storageStatus == PermissionStatus.Granted)
    {
        var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
        {
            Directory = "Sample",
            Name = "test.jpg"
        });

        if (file == null)
            return;

        image.Source = ImageSource.FromFile(file.Path);

        var rekognition = new RekognitionService();
        var faceList = await rekognition.GetFaceDetailsFromLocalFileAsync(file.Path);

        var faceCount = faceList.Count();
        var face = faceList.FirstOrDefault();

        await DisplayAlert("Rekognition", $"Detected: {faceCount} Person\n\nAgeRange: {face.AgeRangeLow} - {face.AgeRangeLow}\nGender: {face.Gender}\nGender Confidence: {face.GenderConfidence}%\nHappiness: {face.HappinessConfidence}%", "OK");
    }
    else
    {
        await DisplayAlert("Permissions Denied", "Unable to take photos.", "OK");
        //On iOS you may want to send your user to the settings screen.
        //CrossPermissions.Current.OpenAppSettings();
    }
}
  • Permission の許可が得られていれば CrossMedia.Current.TakePhotoAsync メソッドで写真を撮り、file に保存
  • MainPage の Image にファイルを表示する

後は Console アプリでもやったように、

  • RekognitionServiceインスタンス化して、GetFaceDetailsFromLocalFileAsync メソッドで faceList を取得
  • (今回はサンプルとして)取得された最初の情報を DisplayAlert で表示

です。

ビルドして動作させると以下のようになります。

f:id:ytabuchi:20181128173052p:plain:w300 f:id:ytabuchi:20181128173124p:plain:w300

iOS だと 81% の確立で女性という結果だったり、Android だと男性になったけど 57歳って…w という不思議な結果が出ていますが、会社の同僚にやってみたらそれっぽいのが出たので、現在の私の風貌が分かりづらいんだろうなw と思っておくことにします。

サンプルのコードを以下に置いておきます。ご興味があれば触ってみてください。

github.com

まとめ

Microsoft Azure と違い、自分のアカウントで Rekognition のリソースを作らなくて良いのは便利だなと思いました。

これについて id:beachside さんと話していたら、Azure の Face などのリソースもインスタンスを立てているわけではなく、Key を作っているだけとのこと。逆に AWS ではリソース(サービス)毎に Key やアクセス権を管理できない(=ユーザー毎の管理になるため)ので面倒だ。と。なるほど、アプローチが違うだけで、同じでしたw

SDK はやっぱり便利です。Rest API で使うこともできますが、認証やレスポンスの JSON の整形を気にすることなく、オブジェクトとしてデータを扱えます。.NET Standard に対応しているので、今回の Core プロジェクトは Xamarin ネイティブからも当然使えます。

AWS SDK for .NET ドキュメント の「開発者ガイド」は非常に少ない記事とサンプルしかないので基本的には API リファレンス を見ていくことになります。

以上です。

Xamarin 気になった方は

Visual Studio 2017 をインストールして触ってみてください。手順書は こちらのエントリー をご覧ください。 学習用リソースJXUG リンクページ に参考資料を纏めてますので併せてどうぞ。

Xamarin の導入支援サービスを始めました。ベースは基本的なアプリを一緒に作ることで Xamarin を使えるようになって頂く内容ですが、ご要望に応じて講習内容のカスタマイズも可能です。詳しくは田淵までお問い合わせください(^^)

Xamarin 有償トレーニング : XLsoft エクセルソフト

Xamarin の情報が欲しい方はこのブログも購読いただいたり、私のTwitterアカウントをフォローいただいたりすると嬉しいです。

私が所属している エクセルソフト の宣伝を少しさせてください。弊社は開発者向けの様々なソフトウェアを扱っています。Office/PDF ファイルを .NET/Java で操作するライブラリ Aspose(アスポーズ)Windows アプリ、Web ページ、iOS/Android アプリの UI テストができる TestComplete などお勧めです(^^) また、Visual Studio Professional/Enterprise with MSDN も販売してますし、日本で売っていない海外のソフトウェア、開発ツールなどを弊社経由で日本円で購入頂くことも可能です。ご興味あれば 弊社ページ を覗いてみてください。

以上です。

【レポ】Prism for Xamarin.Forms入門 Hands-on を開催しました

こんにちは。エクセルソフトの田淵です。

JXUG Prism for Xamarin.Forms入門 Hands-on - connpass

こちらのハンズオンを開催しました。

ドキュメントは @nuits_jp さんが用意してくださったもので、私が皆さんとハンズオンをして、@nuits_jp さんに解説をしてもらう。という私にとっても凄くためになる内容でした。できるとわかるは違うので、ちゃんと分からないと一人でトレーニングとかでやるのは難しそうだなーと感じているところです。

テストも書かないと DI の有難みが分からんよなぁというような話を懇親会で @nuits_jp さんと話していました。

所感

f:id:ytabuchi:20180827191000p:plain:w600

アンケートでは大変良いご評価を頂きました。皆さん楽しんでいただいたようでなによりです。

やっぱりちょっと難しかったみたいですね。下に XAML の補足を書きましたので、ご覧ください。

謝辞

開催にあたり、メンター、スタッフとして関わってくださった @_shunsuke_kawai@mishi_cs@yamamo@nakasho_dev@masatoru@hiro128_777@y_chu5@yoruxama の皆様、ありがとうございます。

引き続き助けて貰えると嬉しいですw

また、終了後に懇親会をしているのですが、初めて参加してくださった方が 4名ほどいらっしゃいました!ありがとうございます!!楽しかったなーと思ってもらえれば何よりです。

補足

内容についてですが、会場で挙手をしてもらったところ、XAML を始めて書くよーって方が結構いらっしゃいましたが、XAML とは?という話が出来なかったのが悔やまれます。

XAML とはオブジェクトのインスタンスを組み⽴てるための⾔語」であって、UI 記述特化言語ではない。という点を踏まえるとハンズオンで書いていた XAML がよりすっと入ってくるのではないかと思います。この言葉は @okazuki さんのスライドをそのまま拝借したものなので、詳しくは以下のスライドをご覧ください。

www.slideshare.net

例えば

PrismHandsOn/04-BindableBaseを利用する.md at master · jxug/PrismHandsOn

LabelText プロパティをバインドして、ButtonCommand をバインドする部分は、XAML だと

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage ...

    <StackLayout HorizontalOptions="Center" VerticalOptions="Center">
        <Label Text="{Binding Message}"/>
        <Button Text="Update Message"
                Command="{Binding UpdateMessageCommand}"/>
    </StackLayout>

</ContentPage>

となっていますが、C# では

public class MainPage : ContentPage
{
    public MainPage()
    {
        var label = new Label();
        label.SetBinding(Label.TextProperty, "Message");

        var button = new Button { Text = "Update Message" };
        button.SetBinding(Button.CommandProperty, "UpdateMessageCommand");

        var stack = new StackLayout
        {
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.Center,
            Children =
            {
                label,
                button
            }
        };

        Content = stack;
    }
}

と書けるわけです。XAMLコンパイルや動的ロードされて C# のコードになるので結局は同じですよね。Prism の自動で ViewModel をバインドしてくれるのも当然動きます(実際に試して動いてびっくりしましたけどw)。

XAML の属性(Attribute)がそれぞれのクラスのプロパティだったりメソッドだったりしている。というのが分かると理解が早いかもしれません。

この後は

このハンズオンをを終了された方は、DI でインジェクションされるオブジェクトをモックに変更することで、テストが簡単になるのを是非実感していただきたいです。(私も実感したいw)

ということで、

github.com

こちらもやってみると良いかもしれません。

また、9/22(土) には今まで JXUG でやったハンズオンをメンターについてもらいながら実施できるハンズオンのハンズオン(?)を開催しますので、ご興味があれば是非ご参加ください。

jxug.connpass.com

なお、アンケートのコメントで

「チャットボットなどのAIを組み合わせたハンズオンをやってみたいです。」とのご意見を頂きましたので、

cogbot.connpass.com

との合同ハンズオンでも企画しましょうかね。面白そうです!

GPSを使う、カメラを使うといったより実用的なハンズオンがあると嬉しいです。」とのご意見がありましたが、Xamarin 公式で Essentials というライブラリを使うと各 OS 固有のセンサーやデバイスが結構共通コードで掛けますので、ドキュメント見てみてください。

docs.microsoft.com

Xamarin 気になった方は

Visual Studio 2017 をインストールして触ってみてください。手順書は こちらのエントリー をご覧ください。 学習用リソースJXUG リンクページ に参考資料を纏めてますので併せてどうぞ。

Xamarin の導入支援サービスを始めました。ベースは基本的なアプリを一緒に作ることで Xamarin を使えるようになって頂く内容ですが、ご要望に応じて講習内容のカスタマイズも可能です。詳しくは田淵までお問い合わせください(^^)

Xamarin 有償トレーニング : XLsoft エクセルソフト

Xamarin の情報が欲しい方はこのブログも購読いただいたり、私のTwitterアカウントをフォローいただいたりすると嬉しいです。

私が所属している エクセルソフト の宣伝を少しさせてください。弊社は開発者向けの様々なソフトウェアを扱っています。おなじみの ReSharper (JetBrains)、 や Atlassian の JIRA, Confluence、Office/PDF ファイルを .NET/Java で操作するライブラリ Aspose(アスポーズ)Windows アプリ、Web ページ、iOS/Android アプリの UI テストができる TestComplete などお勧めです(^^) また、Visual Studio Professional/Enterprise with MSDN も販売してますし、日本で売っていない海外のソフトウェア、開発ツールなどを弊社経由で日本円で購入頂くことも可能です。ご興味あれば 弊社ページ を覗いてみてください。

以上です。

エクセルソフト | ダウンロード | 学習用リソース | JXUG リンクページ | ブログ購読