2009-07-02 (木)
■ HTML_Emoji ライブラリの内部処理について (2)
第2回は、docomo の絵文字についてです。 携帯の文字コードと絵文字の基礎知識 によると、晴れの絵文字は、docomo の携帯では次のようなバイナリで表されます。
# sjisコード print "\xF8\x9F"; # ページのcharset=shift_jisの場合のみ # unicodeのutf-8コード [unofficial] print "\xEE\x98\xBE"; # ページのcharset=utf-8の場合のみで、かつFOMAのみ
これらを相互に変換するにはどうすれば良いのでしょうか? 実は docomo の絵文字の場合は、mb_convert_encoding() 関数を使う際に、 SJIS の代わりに SJIS-win と指定するだけで済みます。
// docomo の絵文字を含んだテキストを、Shift_JIS から UTF-8 に変換 $text = mb_convert_encoding($text, 'UTF-8', 'SJIS-win'); // docomo の絵文字を含んだテキストを、UTF-8 から Shift_JIS に変換 $text = mb_convert_encoding($text, 'SJIS-win', 'UTF-8');
しかし、残念ながらこの方法は、au や SoftBank の絵文字には通用しません。 そのため、他のキャリアの絵文字については、 1文字ずつ地道に変換するような方法が採られることが多いようですが、 HTML_Emoji ライブラリではもっとエレガントな方法を用いています。 次回以降で、その具体的な方法を説明していきます。
2009-07-01 (水)
■ HTML_Emoji ライブラリの内部処理について (1)
今日から何回かに分けて、 HTML_Emoji ライブラリ の内部で行っている絵文字の変換処理について、簡単に解説していこうと思います。 順番としては、次のように進めていく予定です。
- はじめに
- docomo の絵文字
- au の絵文字
- SoftBank の絵文字
- SoftBank (2G) の絵文字
- 別キャリアの絵文字への変換
- まとめ
第1回は、バイナリ形式での絵文字の表記についてです。
携帯の文字コードと絵文字の基礎知識 のページによると、 例えば docomo の携帯の場合、晴れの絵文字は次のようないくつかの方法で表示することができます。
# sjisコード print "\xF8\x9F"; # ページのcharset=shift_jisの場合のみ # unicodeの16進数値文字参照 print ''; # iモード対応HTML4.0対応機種のみ(ほぼ全て) # sjisコードの10進数値文字参照 print ''; # 基本絵文字のみで、ページのcharset=shift_jisの場合のみ # unicodeのutf-8コード [unofficial] print "\xEE\x98\xBE"; # ページのcharset=utf-8の場合のみで、かつFOMAのみ
さらに他のキャリアの情報も見ていってみると、 非公式ながら、どのキャリアの絵文字も SJIS 及び UTF-8 のバイナリコードで表せることが分かります。 そこで HTML_Emoji ライブラリでは、絵文字を次のように扱っています。
- 携帯との入出力は、Shift_JIS のバイナリコードで行う
(ただし SoftBank の場合は UTF-8 での入出力を推奨) - 内部の処理は、UTF-8 のバイナリコードに変換して行う
携帯で絵文字を入力すると、サーバには Shift_JIS のバイナリの形で送られてきます。 逆に、携帯に Shift_JIS のバイナリコードを送ってやると、絵文字を表示することができます。 では、なぜ一旦 UTF-8 に変換するのかというと、Shift_JIS のままでは、
- SoftBank の絵文字のコードが、他キャリアの絵文字と一部重なっている
- 先頭から1文字ずつ取り出して処理しないと、どの部分に絵文字があるのか分からない
といった問題があるからです。 UTF-8 のコードに変換すると、この辺の問題がクリアされて扱いやすくなります。
しかし、普通に mb_convert_encoding() 関数を使うだけでは、絵文字は正しく変換されません。 絵文字を含んだテキストの文字エンコーディングを効率よく変換するには、 キャリア毎に違った方法を採る必要があります。 その具体的な方法について、次回以降に書いていこうと思います。
2009-06-29 (月)
■ 携帯絵文字ライブラリ HTML_Emoji 0.6 を公開しました
HTML_Emoji は携帯の絵文字を変換する PHP 用のライブラリです。 Perl の Encode::JP::Mobile モジュールと同じような処理を、PHP でも行えるようになります。
バージョン 0.5 からの変更点は以下の通りです。
- 文字エンコーディングの変換時に、機種依存文字も変換されるように修正
バージョン 0.5 で mb_substitute_character() 関数を使う方法を導入しましたが、 これだと機種依存文字が含まれていた場合に、変換結果がひどいことになっていました。
そこでもう1度考え直してみたところ、 mb_encode_numericentity() 関数と mb_decode_numericentity() 関数をうまく使えば、 変換処理を非常にすっきりと書けることが分かったので、 バージョン 0.6 ではその方法を用いるよう書き換えました。
この方法の詳細については、別エントリで書く予定です。
2009-06-23 (火)
■ 携帯絵文字ライブラリ HTML_Emoji 0.5 を公開しました
HTML_Emoji は携帯の絵文字を変換する PHP 用のライブラリです。 機能的には、Perl の Encode::JP::Mobile モジュールに近いです。
バージョン 0.4 からの変更点は以下の通りです。
- au, SoftBank の絵文字を Shift_JIS → UTF-8 に変換するのに失敗する場合があったのを修正
- include_path の通ったディレクトリにインストールしないと使えなかったのを修正
文字化けする場合があるとの指摘を受けて調べてみましたが、 どうもこの処理がいけなかったようです。
$text = mb_encode_numericentity($text, $this->_sjismap, 'UCS-2');
半角文字(スペースや改行文字も含む)と Shift_JIS の絵文字が混在したテキストでは、 1文字=1バイトの部分と、1文字=2バイトの部分が存在します。 一方、文字エンコーディングを UCS-2 と指定すると、 問答無用で1文字=2バイトと仮定されてしまいます。 これが原因で、文字の区切りに失敗して、絵文字が壊されていたようです。
今までの方法のままでは対処するのが難しそうでしたので、 問題の起こっていた部分は、mb_substitute_character() 関数を使った変換方法に切り替えました。
2009-06-21 (日)
■ 携帯絵文字ライブラリ HTML_Emoji 0.4 を公開しました
HTML_Emoji は携帯の絵文字を変換する PHP 用のライブラリです。 機能的には、Perl の Encode::JP::Mobile モジュールに近いです。
バージョン 0.3 からの変更点は以下の通りです。
- isSjisCarrier()、isUtf8Carrier() メソッドを追加
携帯用のページの文字エンコーディングは、 SoftBank の場合は UTF-8、それ以外の場合は Shift_JIS にするのが良いのですが、 今までは場合分けの処理を次のように書く必要がありました。
if ($carrier == 'pc' || $carrier == 'softbank') {
// UTF-8 で入出力を行うべき端末用の処理
......
} else {
// Shift_JIS で入出力を行うべき端末用の処理
......
}
バージョン 0.4 で新設された isSjisCarrier(), isUtf8Carrier() メソッドを使うと、 このコードは次のように書き直すことができます。
if ($emoji->isSjisCarrier()) {
// Shift_JIS で入出力を行うべき端末用の処理
......
} else {
// UTF-8 で入出力を行うべき端末用の処理
......
}
'softbank' といった定数を書かなくて済むようになるので、 この方がコードが分かりやすくなると思います。

# rootleaf [便利なソフトを公開して頂き、ありがとうございます。 こちらで作成中のソフトで利用させて頂いていおり、 その際..]
# revulo [どうもありがとうございます。 確かにご指摘の通りなので、次回のバージョンアップ時に反映させたいと思います。 ]