2012年1月29日日曜日

xxd を使って画像などのバイナリデータをソースコードに含める方法

iOS向けのライブラリやフレームワークを作成しているときに、どうしても画像などのバイナリデータをライブラリやフレームワークに含めたくなる時があります。たとえばUI系のフレームワークなどですね。このようなときに、たとえば静的ライブラリ(.aと.h)やフレームワーク(.framework)とセットで画像を一緒に同梱し、ユーザーのXcodeプロジェクトに一緒に含めてもらうという方法もあるのですが、この方法だと画像名がユーザーのプロジェクトに含まれている画像とかぶったりしてはいけませんし、管理が面倒になってしまいます。また、ライセンスがプロプライエタリなライブラリでは、画像などのリソースをあまり積極的にユーザーに公開したくないというニーズがあったりします。

そこでxxdツールのご紹介です。岸川先生に教えていただいたのですが、xxdというツールを使えばバイナリデータをC言語のヘッダファイルとして簡単に出力することができるらしいのです。これを使ってバイナリデータをライブラリ内部のソースコードの一部として配布してみましょう。

xxdはvimに同梱されているので、最初からMac OS Xについてきます。使い方も非常に簡単です。
xxd -i Sample.png
とすると、
unsigned char Sample_png[] = {
  0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
  0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x07, 0xfd, 0x00, 0x00, 0x04, 0x73,
//中略
unsigned int Sample_png_len = 589903;
このような感じでバイナリデータがC言語のヘッダファイルになって出力されます。あとはこれをNSDataにして、UIImageを生成することができます。NSDataを作る際には余計なデータコピーが発生しないdataWithBytesNoCopy:length:freeWhenDone:を使うことをお勧めします。
NSData *data_Sample_png = [NSData dataWithBytesNoCopy:Sample_png length:Sample_png_len freeWhenDone:NO];
UIImage *image = [UIImage imageWithData:data_Sample_png];