ちょっとPNGの中身(ヘッダー情報とか画像以外の情報も)を見てみたくなったので、Rubyでスクリプトを書いてみました。

PNGファイルをパースする
以下のコードのポイントは「バイナリファイルの開き方」「バイナリファイルの走査」「PNGフォーマットに基づいたチャンク読み込み処理」「String#unpackによるバイナリデータの変換」です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | ######################################## # testPNG.rb # 2010/04/29 ######################################## # 指定PNGファイルの情報を処理します. def checkPNGInfo( filename, logfile ) png = File.open( filename, "rb" ) # バイナリモード読み込み用モード. if png != nil then # PNGファイルシグネチャ .. 8byte固定(89 50 4E 47 0D 0A 1A 0A). png.read( 8 ) # IHDRチャンク イメージヘッダ .. 25byte固定. png.read( 25 ) # チャンク毎に読み進める. loop do if png.eof? logfile.print "DONE!\n" break; end # read Length (4byte) length = png.read( 4 ).unpack('N') # "big endian unsigned 32bit"で1文字読み込み. length = length[0].to_i logfile.print "length["+length.to_s+"]\n" # read Type (4byte) type = png.read( 4 ) logfile.print "type ["+type+"]\n" # read contents data = png.read( length ) # read CRC (4byte) crc = png.read( 4 ) logfile.print "\n" end end end #------------------------------------------------------------# # main #------------------------------------------------------------# f = File.open("log.txt", "w") # ログ出力ファイル. if ARGV[0] == nil print "usage: ruby testPNG.rb <filename.png>" else checkPNGInfo( ARGV[0], f ) end |
String#unpack
バイナリデータから数値への変換オプションにはいろいろな指定があるのですが、一番重要なのは、次の4つだと思います。
- n: big endian unsigned 16bit
- N: big endian unsigned 32bit
- v: little endian unsigned 16bit
- V: little endian unsigned 32bit
上記コードでは、21行目で unpack(‘N’) と読み込んでいます。
参考サイト
参考にしたのは下記のサイトです。ありがとうございました!
[AD]
↓失敗から学ぶ。その1.
システムはなぜダウンするのか 知っておきたいシステム障害、信頼性の基礎知識
著者/訳者:大和田 尚孝
出版社:日経BP社( 2009-01-15 )
定価:¥ 2,520
Amazon価格:¥ 2,520
単行本(ソフトカバー) ( 312 ページ )
ISBN-10 : 482228381X
ISBN-13 : 9784822283810
↓失敗から学ぶ。その2.
著者/訳者:日経コンピュータ
出版社:日経BP社( 2002-12-06 )
定価:¥ 1,575
単行本 ( 208 ページ )
ISBN-10 : 4822207846
ISBN-13 : 9784822207847






