前回は画像フォーマットとしてraw画像を扱いました。
このフォーマットだとデコードが必要ないのですぐに画像データにアクセスできましたが、画像サイズやビット深度などの情報がわからないので、あらかじめそれらの情報は既知であるものとしていました。
そこで、今回はヘッダのあるフォーマットを扱うことにします。
ppm/pgm/pbm 画像
UNIXでは一般的な画像フォーマットです。
(参考:画像ファイルの扱い方 (2) -PPM/PGM/PBM形式 (1))
PPM形式(Portable PixMap file format) はRGBカラー画像を扱うためのフォーマット。
へッダ部はテキスト形式、画像データ部はテキスト/バイナリを選択できます。
PGM形式(Portable GrayMap file format) はグレースケールの画像、PBM形式(Portable BitMap file format) は2値画像を扱うフォーマットです。
このフォーマットは圧縮やカラーパレットによる色の割当などを行っていない状態でデータが保存されているため、画像解析が行いやすく研究用途でもよく用いられています。
ただし、データは無圧縮なのでjpgやpngなどの圧縮画像と比べてサイズはかなり大きくなります。
(XGAのカラー画像(壁紙サイズ)だと約2MB(1024*768*3バイト))
ここではカラー画像を扱いたいのでPPM画像のヘッダを見ていきます。
PPMにはascii形式とraw形式がありますが、後者のraw形式(画像データ部がバイナリ)を扱います。
・PPMフォーマットのヘッダ例 (改行はLF:Line Feed)
1 2 3 4 5 |
P6 # comments... 640 480 255 ここから後は画像データがRGBRGBRG...の順で並んでいる |
最初のP6というのはRGB24ビットカラー raw形式であるということを表しています。
ちなみにここがP3の場合はascii形式のファイルになります。
#から始まる行はコメントで、ヘッダ部には自由にコメントを入れることができます。
次の行の640 480というのは画像サイズ(width height)を表し、スペースで区切られています。
最後の255は画像データの最大輝度値で、この場合は0?255までの値を取ることを表しています。
実際にこの画像のヘッダ部を覗いてみると、(ここではブログに載せるためjpg画像にしてあります)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
・・・ var stream:URLStream = new URLStream(); stream.load(new URLRequest("./assets/milkdrop.ppm")); stream.addEventListener(Event.COMPLETE, readPPM); stream.addEventListener(IOErrorEvent.IO_ERROR, errorHandler); private function readPPM(e:Event):void { var imageData:ByteArray = new ByteArray(); var header:String; e.target.readBytes(imageData); // PPMフォーマットのヘッダサイズは不定なので、ここでは適当に256バイト分読む for(var i:int=0;i<255;i++){ header += imageData[i]; } trace(header.replace(/(\d{2})/g, "$1,")); ・・・ |
出力
80,54,10,35,32,83,73,68,66,65,10,50,53,54,32,50,53,54,10,50,53,53,10,…
このように10進数の数字が並んでいます。(ヘッダ部はテキスト)
ただのASCIIコードなのでこれを前から順に変換していくと、(ASCII文字コード表)
P,6,LF,#,SP,S,I,D,B,A,LF,2,5,6,SP,2,5,6,LF,2,5,5,LF,…..(LF:Line Feed、SP:スペース)
つまり、
1 2 3 4 5 |
P6 # SIDBA 256 256 255 ...... |
となり、RGB24ビットカラー raw形式、256×256[pixel]、最大輝度値255 の画像であることがわかります。
ちなみにコメント行にある”SIDBA”というのは、標準画像データベースのことです。
(有名なlenna画像もSIDBAにある)
画像ヘッダの解析を行うことで、画像データにアクセスする際に必要な情報が全て取得できます。
ここだけ見ると画像処理ではなく文字列処理の分野になりますね。
“#”と”LF”さえしっかり押さえておけば、あとは正規表現などで普通に数字を読むだけです。
さて、これでやっと画像処理をする準備が整いました。
関連記事:
ByteArrayで画像処理入門以前
2 Thoughts