PNG画像をちょっと編集してみたくなってフォーマットを調べてみました。
と言っても、画像を編集したいわけではなくPNGファイル内に格納されているテキストについて編集したかったわけです。
結果的にはうまくいって、任意の文字を追加できるようなプログラムを作ることが出来ました(C#)。
詳しくは以下などにPNGフォーマットのドキュメントがあります。libpngでもいいかもな話ですがC#だけで実装したかったんです。
http://www.w3.org/TR/PNG/
■PNGフォーマットの構造
細かいことは調べてないし、書きませんがPNGフォーマットはWAVフォーマットや他のフォーマットとほとんど同じように、チャンク構造になっています。ヘッダ8バイト、それから複数のチャンクだけで構成されます。
■ヘッダ
PNGのヘッダは以下8バイトで固定です。0x89 0x50 0x4e 0x47 0x0d 0x0a 0x1a 0x0aテキストと間違ないためのコードであったり、意味があるそうです。
0x504e47は「PNG」。
0x0d0aとか0x1a0aとかは感のいい方なら分かりますよね。
■チャンク
ひとつのチャンクの構造は以下の通りです。エンディアンはビッグエンディアン。
0x00 4byte Lengthデータの長さが4バイト、FourCCが4バイト4文字、データ、そしてFourCCとデータ部のCRCを計算したものをCRCに入れます。
0x04 4byte FourCC
0x08Data
0x08+Length 4byte CRC
ISO-3309とITU-T-V42で規定されたCRC32ビットが入っています。
http://www.libpng.org/pub/png/spec/1.2/PNG-CRCAppendix.html
チャンクの先頭には「IHDR」という画像の基本情報が入っているチャンクがあるべきと書いてあります。
■テキストチャンク
テキスト向けのチャンクのタイプはいろいろありますが、「tEXt」というチャンクが文字情報を入れるためのベーシックなものです。FourCCは「tEXt」。
データ部が文字なのですが、Key&Valueで構成されその間を0x00で仕切ります。
つまり、「Key文字列 + 0x00 + Value文字列」です。終端に0x00を入れる必要はありません。
Key文字列は1〜79文字とし、Valueはまったく存在しなくてもいい模様。
利用可能な文字はLatin-1と規定されています。
■キーワード
キーワードには以下のようなものがあります。上記で言うKey文字列のその内容を意味づけた一覧です。Title | Short (one line) title or caption for image |
---|---|
Author | Name of image's creator |
Description | Description of image (possibly long) |
Copyright | Copyright notice |
Creation Time | Time of original image creation |
Software | Software used to create the image |
Disclaimer | Legal disclaimer |
Warning | Warning of nature of content |
Source | Device used to create the image |
Comment | Miscellaneous comment |
■ずばりPNGファイルの文字情報を追加するには
元々同じキーワードがファイルに存在していた場合は差し替えるなどの操作が必要ですが、チャンク情報を解析した上で、追加したい「tEXt」チャンクデータを作成してファイルに挿入するだけです。……って言うのは簡単ですがね。