漢字フォントをイメージファイル(png)に埋め込む2015年08月26日 20:01

漢字の神経衰弱パズルを作ろうと思い立つ。WinRT XAML ToolkitのImageToggleButtonを用い、ボタンを押すと、カードの裏の漢字を表示する。必要になるのが、漢字フォントを埋め込んだイメージファイル(png)。1000文字以上あるので、事前に用意せず、都度、作りたい。

ところが、ストアアプリ(UWP)では、Font class、Graphics class、Bitmap class などは使えない。GDIでの手法は使えない。見栄えの問題はあるが、RenderTargetBitmapを使うことにする。元来、画面に表示するイメージのサムネールを作る用途などで使われる。

Fontを埋め込んだpngファイル

上段のGridにTextBlockを置き、文字を入れ替えながら、表示をイメージファイルに落とし込む。下段のGridにはImageToggleButtonを並べる。作成したイメージファイルは、ImageToggleButtonのImageSourceに登録する。

Fontをpngファイルに埋め込む - XAML

該当するXAMLの定義部分。内側のGridがイメージの取り込み元。その中のTextBlockを切り替える。

Font

コード例。RenderTargetBitmapのRenderAsyncでイメージを生成。Gridのサイズとは異なってよい。多様な画面に対応するため、大きめで用意。GetPixelsAsyncで生成したデータを取り込む。byte列に変更してから、BitmapEncoderでファイルに出力。

一時フォルダ

出力先は、一時フォルダ。

それなりに手間はかかるが、なんとかできるもの。

SJISのCSVファイルの読み込み2015年08月26日 20:51

アプリで使う漢字データを、Excel2010で作成し、CSVで保存。そのまま取り込むと文字化け。Cygwinを起動し、"od -t x1"で覗くと、SJIS。Unicodeにしなくては。あらかじめファイルを変換してしまう方が楽だが、ストアアプリ(UWP)での変換も習得しておいたほうがいい。

SJISのCSVファイルを読み込んでUTF-8にする

そのままでは、SJISは使えない。最初の2行のおまじないが要る。

CSVファイルに対してFileStreamを用意し、StreamReaderで読み込む。最初、Encoding(sjis)を指定しなくて失敗。読み込んでから壊れたデータをいくらコード変換しようとしてもだめ。

読み込んだStringをGetBytesでbyte列に変換の上、Encoding.ConvertでUTF-8にコード変換。ここから逆戻り。byte列をchar配列に変換の上、Stringに戻す。ここまで来てはじめて、Splitでカンマ区切りの文字列を分解。

変換ばかりで手間がかかるが、まあ、できる。

ImageToggleButtonへのImageSource登録2015年08月26日 21:50

WinRT XAML ToolkitのImageToggleButtonでは、Buttonの8つの状態別にイメージファイルを登録し、状態ごとに様々な外観を提供できる。

ImageToggleButtonのXAML定義

Gridで作った盤上にImageToggleButtonを並べるXAML定義。見えている部分では、通常の状態を示すNormalStateImageSourceにイメージファイル(png)を設定している。この設定はダミーで、プログラムで必要なイメージに付け替える。

ImageToggleButtonへのImageSource登録

付け替えるイメージファイルは、一時フォルダに置く。ファイルは、"ms-appdata:///temp/"でアクセスできるとある。

最初は、BitmapImageのUriSourceにこのパスを登録し、ImageToggleButtonの各ImageSourceに設定すれば済むと考えたが、例外になる。ネットワークアクセスのための機能の指定も足りないと言われる。パスが"http:"や"ftp:"でなく不正だ、と言ってくる。これが通る場所もあるのだが。

こうなると手間はかかるが正攻法。イメージファイルをStreamとしてオープンし、RandomAccessStreamに変換の上、BitmapImage.SetSourceAsyncで登録。ここでは、ボタンが押された状態に対応するPressedStateImageSourceが登録先。対象のImageToggleButtonは、親のGridからFindNameで検索。