SIN@SAPPOROWORKSの覚書

C#を中心に、夜な夜な試行錯誤したコードの記録です。

Xamarin.Forms 機械翻訳

【 Xamarin 記事一覧 】

f:id:furuya02:20150302035651p:plain:w400:left
今回は、機械翻訳を実装してみました。

WebAPIでかなり高速な翻訳や読み上げが可能なので、色々面白そうです。

図は、Webページの英文をコピペして翻訳しているようす。

Microsoft Translator

f:id:furuya02:20150302035809p:plain:w400:left
現時点での翻訳サービスは、googleとMicrosoftの2択のようです。googleの方は有料になってしまったようなので、今回は、Microsoftのサービスを使用しました。

Microsoftのオンライン機械翻訳サービスはエンドユーザー向けに「Bing Translator」という名前で提供されており、そのバックで動作しているのが「Microsoft Translator」のようです。

f:id:furuya02:20150302035827p:plain:w400:left



「Microsoft Translator」は、1 ヶ月あたり200万文字まで無料で利用可能です。

利用手順

「Microsoft Translator」の利用するための手順は、下記のとおりです。

Live ID 取得
Windows Live IDが必要です。既に取得している場合は、この作業は必要ありません。

サブスクリプション登録
Microsoft Translator データに対して、サブスクリプション登録をします。
f:id:furuya02:20150302035843p:plain:w400:left
Microsoft Translator | Microsoft Azure Marketplace


アプリケーション登録
f:id:furuya02:20150302035855p:plain:w400:left
https://datamarket.azure.com/developer/applications/
「顧客の秘密(シークレットキー)」は自由に決定することができるようです。また、クライアントアプリを作成する場合「リダイレクトURL」には、無効なURLを指定します。

ここで設定した、「クライアントID(ClientId)」と「顧客の秘密(ClientSecret)」が、実装時に必要になります。

翻訳クラスの実装

「Microsoft Translator」には、読み上げや、辞書引きなど、いくつかの機能がありますが、今回は「テキスト翻訳」のみを実装しています。
Xamarin.FormsのPCLから利用するために、HTTP通信用のHttpClientとJSON処理用のJson.NETをインストールしました。
※HttpClientはデフォルト非同期対応で、非常にシンプルに記述できるので惚れます。


PM> Install-Package Microsoft.Net.Http
PM> Install-Package Newtonsoft.Json

f:id:furuya02:20150302040006p:plain

実装したコードは、下記のとおりです。ざっくり言ってしまうと、アクセストークを取得して、WebAPIをコールしているだけです。
詳しくは、下記のリンクをご参照ください。(最後の方にサンプルコードもあります)
https://msdn.microsoft.com/ja-jp/library/ff512421.aspx

class Translator {
    private const string ClientId = "TranslatorSample001";
    private const string ClientSecret = "iYbcPHxxxxxxxxxxxx7IVE=";

    private string _token;

    private async Task<bool> InitializeToken() {
        if (_token == null) {
            var client = new HttpClient();
            const string url = "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13";
            var content = new FormUrlEncodedContent(new Dictionary<string, string> {
                {"client_id", ClientId},
                {"client_secret", ClientSecret},
                {"scope", "http://api.microsofttranslator.com"},
                {"grant_type", "client_credentials"},
            });
            var response = await client.PostAsync(url, content);
            //JSON形式のレスポンスからaccess_toneを取得する
            var adm = JsonConvert.DeserializeObject<AdmAccessToken>(await response.Content.ReadAsStringAsync());
            _token = adm.access_token;
            return true;
        }
        return false;
    }

    
    //JSON形式のレスポンスをデシリアライズするためのクラス
    [DataContract]
    public class AdmAccessToken {
        [DataMember]
        public string access_token { get; set; }

        //access_token以外は、取得しないので省略
    }

    public async Task<string> Get(string str) {

        //初回のみaccess_tokenを取得する
        if (_token == null) {
            await InitializeToken();
        }
        var client = new HttpClient();
        var url = string.Format("http://api.microsofttranslator.com/v2/Http.svc/Translate?text={0}&to=ja"
            , WebUtility.UrlEncode(str));
        client.DefaultRequestHeaders.Add("Authorization", "Bearer " + _token);
        var response = await client.GetStringAsync(url);
        //XML解釈
        var doc = XDocument.Parse(response);
        return doc.Root.FirstNode.ToString();
    }
}

メイン画面

先の翻訳機能を使用するメインの画面は、入力欄(Editor)と出力欄(Label)と翻訳開始のボタン(Button)を配置しただけです。

namespace Translator {
    public class App : Application {
        public App() {
            MainPage = new MyPage();
        }

    // ・・・省略・・・

    }

    internal class MyPage : ContentPage {

        private readonly Translator _translator = new Translator();

        public MyPage() {
            //翻訳前のテキスト入力
            var editor = new Editor {
                HeightRequest = 200,
                Text = "Hello world"
            };
            //WindowsPhoneの場合だけ、フォーカスが無いときに文字が見えないので背景色を指定する
            if (Device.OS == TargetPlatform.WinPhone) {
                editor.BackgroundColor = Color.Teal;
            }
            //翻訳後のテキスト表示
            var label = new Label();
            //翻訳開始のボタン
            var button = new Button {
                Text = "Translate",
                Command = new Command(async () => {
                    label.Text = await _translator.Get(editor.Text);
                })
            };

            Content = new StackLayout() {
                Padding = new Thickness(10, Device.OnPlatform(30, 10, 10), 10, 0),
                Children = {editor, button, label}
            };

        }
    }
}

図は、WindowsPhoneとAndroidで動作しているようすです。

f:id:furuya02:20150302040101p:plain:w400f:id:furuya02:20150302040107p:plain:w400

コードはGithubに置きました。


furuya02/Xamarin.Forms.Translator · GitHub

参考資料

Microsoft Translator - Web localization
第38回 使ってみようMicrosoft Translator:使ってみよう! Windows Live SDK/API|gihyo.jp … 技術評論社
Translate Method



【 Xamarin 記事一覧 】