Xamarin.Forms 機械翻訳
今回は、機械翻訳を実装してみました。
WebAPIでかなり高速な翻訳や読み上げが可能なので、色々面白そうです。
図は、Webページの英文をコピペして翻訳しているようす。
Microsoft Translator

現時点での翻訳サービスは、googleとMicrosoftの2択のようです。googleの方は有料になってしまったようなので、今回は、Microsoftのサービスを使用しました。
Microsoftのオンライン機械翻訳サービスはエンドユーザー向けに「Bing Translator」という名前で提供されており、そのバックで動作しているのが「Microsoft Translator」のようです。
「Microsoft Translator」は、1 ヶ月あたり200万文字まで無料で利用可能です。
利用手順
「Microsoft Translator」の利用するための手順は、下記のとおりです。
Live ID 取得
Windows Live IDが必要です。既に取得している場合は、この作業は必要ありません。サブスクリプション登録
Microsoft Translator データに対して、サブスクリプション登録をします。
Microsoft Translator | Microsoft Azure Marketplace
アプリケーション登録

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
実装したコードは、下記のとおりです。ざっくり言ってしまうと、アクセストークを取得して、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で動作しているようすです。
コードはGithubに置きました。
furuya02/Xamarin.Forms.Translator · GitHub
参考資料
Microsoft Translator - Web localization
第38回 使ってみようMicrosoft Translator:使ってみよう! Windows Live SDK/API|gihyo.jp … 技術評論社
Translate Method