まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

タグ:japanese

先日、HTML5 Canvas のサーバーサイド版である Node-Canvas を紹介しました:
Node.js から使えるサーバーサイド Canvas : node-canvas


HTML5 Canvas と互換性のある API を使って動的に Canvas 上に描画をします。実際には単に描画をするだけでなく、描画した内容を画像として取り出したりすることで、サーバー側の JavaScript で動的に画像ファイルを生成することができるようになり、とても便利なライブラリです。

実際に使っていて、1点問題気になることがありました。開発中は(日本語環境バッチリな)自分のマシンを使って動作テストなどを行うので気が付きにくいのですが、実際の本番サーバー上で動かした際にキャンバス上に描画した日本語文字列が化けてしまうケースを発見しました。

例えばこのようなコードを実行して、サーバーサイドで画像を動的に生成したとします:
  :
var fs = require( 'fs' );
var Canvas = require( 'canvas' ),
    Image = Canvas.Image;

  :

var canvas = new Canvas( 300, 300 );
var ctx = canvas.getContext( '2d' );

//. 赤い直線を1本描画する
ctx.beginPath();
ctx.moveTo( 100, 100 );
ctx.lineTo( 200, 200 );
ctx.strokeStyle = 'red';
ctx.stroke();

//. 文字列を表示する
ctx.fillText( 'ハローワールド!', 10, 30 );

//. 画像データをファイルにして保存する
var b64 = canvas.toDataURL().split( ',' )[1];
var buf = new Buffer( b64, 'base64' );
fs.writeFileSync( __dirname + '/images/aaa.png', buf );

  :


このコードを Node.js で実行すると、./images/aaa.png というファイル名で動的に画像ファイルが生成されて保存されます。が、その時に生成される画像で「ハローワールド!」と明示されている文字列はサーバー実行環境によって正しく表示されたり、されなかったりします:

(正しく表示される場合)
2017052901

(文字化けを起こす場合)
2017052902


これはサーバー OS 側に日本語フォントが導入されているかどうかで決まります。特にクラウド環境においては OS は(デフォルトでは)英語版が用意されることが多く、そのまま利用しても日本語フォントが用意されていないため、「ハローワールド」という文字列を正しく描画できず、結果として文字化けを起こしてしまうことになります。

ということは、仮に文字化けを起こしても、OS に日本語フォントを導入した上でアプリケーションサーバーを再起動すれば回避できる、ということになります。

が、ここで問題が発生します。IBM Bluemix のような PaaS 環境の場合、OS 環境設定の自由度が低く、用意されたプラットフォームをカスタマイズして使うハードルが高くなります。現に SSH でログインすることはできますが apt-get などは使えません。またフォントファイルを後から無理やりコピーしてもアプリケーションサーバーを再起動するとそのファイルは消えてしまいます。このような自由度があまり高くないプラットフォーム上で日本語を正しく表示させることが結構難しかったりします。

そしてなんと更に、Node-Canvas の Issue ボードによると、この部分にはどうもバグがあるらしく、(2017/May/29 現在)ステータスが Open になっているので、まだ解決できていない模様でした:
https://github.com/Automattic/node-canvas/issues/783


・・・と、とても困った状況なのですが、結論から言うとなんとかアプリケーション側の工夫で回避することができました。まずは日本語フォントが必要になるので、フリーの日本語フォントを適当にダウンロードしてきます。例えば eFont プロジェクトから配布されているさざなみフォントの最新版を使うことにします。アーカイブファイル(*.tar.bz2)をダウンロード&展開し、sazanami-***.ttf というファイルをアプリケーション内の fonts/ ディレクトリに格納しておきます:
2017052903

(以下のコードではゴシックフォントしか使いませんが、とりあえず明朝フォントと合わせて展開しておきます)


そしてコードの該当部分を以下のように変更します:
  :
var fs = require( 'fs' );
var Canvas = require( 'canvas' ),
    Image = Canvas.Image;

  :

var canvas = new Canvas( 300, 300 );
var ctx = canvas.getContext( '2d' );

//. 赤い直線を1本描画する
ctx.beginPath();
ctx.moveTo( 100, 100 );
ctx.lineTo( 200, 200 );
ctx.strokeStyle = 'red';
ctx.stroke();

//. フォントを強制指定する
var Font = Canvas.Font;
var myFont = new Font( 'myFont', 'fonts/sazanami-gothic.ttf' );
ctx.addFont( myFont );
ctx.font = '20px myFont';

//. 文字列を表示する
ctx.fillText( 'ハローワールド!', 10, 30 );

//. 画像データをファイルにして保存する
var b64 = canvas.toDataURL().split( ',' )[1];
var buf = new Buffer( b64, 'base64' );
fs.writeFileSync( __dirname + '/images/aaa.png', buf );

  :


これで実行すると、フォントが指定のものに強制指定され、日本語が化けずに表示できるようになります(下図は IBM Bluemix 環境下で実行した結果です):
2017052904


なお、上記の方法を使う場合、Ubuntu はこのままでも動くのですが、Mac OS X 環境においては Pango ライブラリを無効にした上で実行する必要があります。具体的には Node-Canvas を npm install した後で、node_modules/canvas/binding.gyp ファイルを編集し、15行目の値を 'false' にする(8行目と同じにする)作業を行い、再度 npm rebuild した上で node コマンドを実行する必要がありました。ご注意ください。


前回の続きです:
ラズパイに Kali Linux をインストールする

ラズベリーパイに Kali Linux のイメージを導入して起動する、という所までを紹介しました。これで OS としては動きますが、このままの状態では以下の2点の問題があります:
(1) (Kali Linux の真髄でもある)ペネトレーションテスト用ツールがまだ足りない
(2) ウェブブラウザなどで日本語表示ができない

この2つの問題を解決するためのセットアップを行います。

まずは (1) の問題、これは最新版のリポジトリを使って、モジュールを最新版に更新すれば解決します:
# apt-get update
# apt-get upgrade

特に2番目のコマンドの実行にはかなり時間がかかりますが、一晩かけるつもりで寝る前に実行するなどしてください。

次に (2) の問題、こちらは日本語フォントが含まれていないのでデフォルト状態ではブラウザで日本語ページを見たりしても文字化けしてしまうのでした。これは適当な日本語フォントを導入することで解決できます:
# apt-get install fonts-vlgothic


ここまで行うことでペネトレーションテスト用ツールがアプリケーションメニューからも利用できるようになります。またブラウザで日本語ページを見ても文字化けせずに表示できるようになります:
kali


 

ラズベリーパイベースのラップトップ PC である PiTop を、デスクトップ環境として整備しています。さすがにメイン機として使うのは・・・ ですが、サブ機として支障なく使える程度にできないだろうか、と思っています。

ただ改めてラズパイを使ってみると、色々足りない部分も見えてきます。それら足りない部分を導入する手順を調べてみました。ちなみに PiTop で使う OS は Raspbian Jessie とします。


日本語表示

導入手順によってはインストール時にある程度設定できるので、初めから日本語表示ができる環境を手にしている人もいるかもしれませんが念のため。 以下の手順で日本語が正しく表示できるように(□みたいな文字にならないように)して、更に日本語フォントを導入します:
$ sudo raspi-config

"Innternnationalisation Options" 選択
"Change Locale" 選択
"ja_JP.UTF-8" 選択し、デフォルト言語に設定し raspi-config を終了
$ sudo apt-get install ttf-kochi-gothic xfonts-intl-japanese xfonts-intl-japanese-big
2016072501



日本語入力

日本語が正しく表示できても、入力となると別の設定が必要です。今回は IBUS を使って日本語を入力できるよう、必要なアプリを導入して日本語入力設定を行います:
$ sudo apt-get install ibus-anthy

メニューから「設定」-「IBUS の設定」を選択
「インプットメソッド」タブで「日本語 - Anthy」を設定

2016072502

これで画面右上の IBUS アイコンをクリックすることで入力言語を切り替えることができるようになります。


Eclipse

自分がこれがないと Java アプリが作れません。というほど依存している統合開発環境である Eclipse のラズパイ版を導入します。ラズパイ用の Pleiades (ちなみに Eclipse 3.8 ベース)が用意されていたとは・・・
$ sudo apt-get install pleiades

20160728



スクリーンショット

ラズパイでスクリーンショットを撮るにはいくつかの方法があります。自分はこれまでは直接スクリーンショット撮ることはなく、VNC 経由で別PCから画面ショットを撮っていました。が、今回は折角デスクトップ環境を手に入れることができたので、単体で取得できる scrot を使うことにします:
$ sudo apt-get install scrot


その他

個人的によく使う screenvim を入れておきます:
$ sudo apt-get install screen vim

screen と同じくらい使う tmux も Raspbian 上で使うことができそうです:
$ sudo apt-get install libevent-dev libncurses5-dev
$ cd /tmp
$ wget https://github.com/tmux/tmux/archive/2.2.tar.gz
$ tar xvfz 2.2.tar.gz
$ cd tmux-2.2
$ ./configure && make
$ sudo make install

とあるメインフレームコンテストに参加するために IBM 3270 環境が必要になるのでコマンドライン版を導入します:
$ cd /tmp
$ mkdir 3270
$ cd 3270
$ wget http://downloads.sourceforge.net/project/x3270/x3270/3.3.14ga11/suite3270-3.3.14ga11-src.tgz
$ tar xavf suite3270-3.3.14ga11-src.tgz
$ cd c3270-3.3
$ ./configure && make
$ sudo make install

自分はいい歳したオッサンなので、オッサンが喜ぶような X11 アプリをまとめて導入しておきます:
$ sudo apt-get install x11-apps

これで懐かしい "xeyes" などが使えるようになります:
2016073105



その他プログラミング言語やミドルウェアについては適当に。

IBM Bluemix から提供されているワトソン関連の API の中には、入力テキストを元に性格を分析する、という Perosnality Insights API があります:
2016040103


僕の以前のブログエントリでもリリース時にレポートしています。その時の様子はこちらを参照ください:
Bluemix の性格分析 API が正式サービス化  (←改めて見ると中身のないエントリだ・・・)



この Personality Insights API のリリースノートを眺めていて気付いたのですが・・・
2016040101


なんと、いつの間にか日本語対応していたっぽいです! POST 時の JSON パラメータか、あるいは HTTP リクエストヘッダで Content-Language を ja にすればよい、とのこと。

今日(2016/Apr/01)エイプリルフールだけどマジか!? ということで試してみました。HttpClient ライブラリを使った Java でのサンプルですが、こんな感じで:
String pi_url = "https://gateway.watsonplatform.net/personality-insights/api";
String pi_username = "(ユーザー名)", pi_password = "(パスワード)";
String body = "・・・・・(日本語テキスト)・・・・・";

HttpClient client = new HttpClient();
byte[] b64data = Base64.encodeBase64( ( pi_username + ":" + pi_password ).getBytes() );

PostMethod post = new PostMethod( pi_url + "/v2/profile" );
post.setRequestHeader( "Content-Language", "ja" ); //. 日本語であることを宣言
				
post.setRequestHeader( "Authorization", "Basic " + new String( b64data ) );
post.setRequestHeader( "Content-Type", "text/plain" );
post.setRequestBody( body ); //. 日本語テキストをポスト
				
int sc = client.executeMethod( post );
String out = post.getResponseBodyAsString(); //. 結果


結果の out 変数を出力すると、このような値が含まれていました:
2016040102

 ↑僕の最近のツイッターからインプットテキストを作りました。「チャレンジが足りない」とか言われてる気がする・・・ 



結果の JSON テキストが返ってきています。しかも "proccessed_lang" の値がちゃんと "ja" になっているので、日本語テキストとして処理された、ということになります。JSON の結果そのものは英語で返されていますが、日本語のテキストを元に性格分析ができるようになった、ということです。おおーっ!これは使いみちありそうだぞ。

例えばメールや SNS など、特定の1名のユーザーが入力したテキスト情報を充分な量集めてこの API を実行すれば、そのユーザーの性格という属性の塊を得ることができるようになるわけです。電話などでの会話の音声データをテキスト化してインプットデータとする、ということも考えられます。そして Personality Insights API を実行した結果を使って、そのユーザーの性格にあった対応や返答をプロアクティブに行うこともできるようになるわけで、それが日本語でも可能になったわけです。

色々楽しみが増えました。なお Personality Insights API の具体的な使い方を含めた API リファレンスはこちらを参照ください:
https://watson-api-explorer.mybluemix.net/apis/personality-insights-v2#!/personality-insights/


↑この API リファレンス内の記述だと、まだ英語とスペイン語のみ、という記述になってますね。ドキュメントが追いついてないくらいの最新情報でした!


連休中にふと気付いた、Bluemix / Watson デベロッパーとしては大きめのニュースです。

IBM Bluemix から提供されている Watson API 群の1つ、Text to Speech 。これは与えたテキストを自然な音声のオーディオデータにして返してくれる API サービスです。で、このサービスのカタログページ(https://console.ng.bluemix.net/catalog/text-to-speech/)をブラウザの言語設定を日本語にして参照すると、今(2015/Sep/23)も以前と特に変わらずこんな感じですが・・・
2015092301

 
ブラウザの言語設定を英語にして同ページにアクセスすると・・・
2015092302


こ、これはっ!
2015092303

 
念のため、Watson Developer 向けデモページ(http://text-to-speech-demo.mybluemix.net/)を開いてみると、言語サンプルに「日本語 - エミ(女性)」なる選択肢が含まれています!!サービスがいつの間にか日本語対応していたのか!?
2015092305


念のため、実際に API として利用できるかどうかを試してみました。Bluemix 上で Watson の Text to Speech サービスを追加し、接続情報(credentials 内の url と username と password)を参照します:
2015092307


この username と password の情報を使って、ウェブブラウザ(Chrome か FireFox)で以下の URL にアクセスします:
https://(usernameの値):(passwordの値)@stream.watsonplatform.net/text-to-speech/api/v1/synthesize?voice=ja-JP_EmiVoice&text=今日はいい天気ですね


するとこんな画面になって、女性の声で「今日はいい天気ですね」と聞こえてきます。データは audio/ogg で送られてくるので、この音声フォーマットを再生することのできるブラウザを使うか、或いは受け取る側でこの音声データを再生することができれば、その場で再生されるはずです:
2015092306


もちろん、これはあくまで API なので、実際のアプリケーションではそのまま再生する必要はなく、データベースに格納してもいいし、この音声データを別の API にポストしてもいいわけです。 ともあれ、いつの間にか Text to Speech が日本語対応していました!

なお、Text to Speech API のリファレンスはこちらを参照ください:
http://www.ibm.com/smarterplanet/us/en/ibmwatson/developercloud/apis/#!/text-to-speech/


で、「エミ」って誰??

このページのトップヘ