SATOXのシテオク日記

~ふもっふ、ふもふも~

PNGファイルの文字情報をいぢってみる

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
  0x04 4byte FourCC
  0x08 Data
  0x08+Length 4byte CRC
データの長さが4バイト、FourCCが4バイト4文字、データ、そしてFourCCとデータ部のCRCを計算したものを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」チャンクデータを作成してファイルに挿入するだけです。
……って言うのは簡単ですがね。