pythonでpngファイルを開いてみる2

意外と画像データまで遠いぞ

PNGフォーマットの続き。この前はSignatureを読み込みました。
Signatureも含め、PNGフォーマットの基本は以下となっているようです。

  • Signature 8byte
  • IHDRチャンク 25byte
  • IDATチャンク Nbyte
  • IENDチャンク 12byte

データのまとまりをチャンクと言うらしい。IHDRがheaderで、IDATがimageデータですね。
imageデータをバリバリ弄りたいのでIHDRを飛ばしてもよいのですが、そこはまあお勉強。すべてを詳らかにしていく勢いで。

f = open('フルパス/lenna.png','rb') 
signature = f.read(8)
length = int(f.read(4).hex(),16)
c_type = f.read(4)
i_width = int(f.read(4).hex(),16)
i_height = int(f.read(4).hex(),16)
bit_depth = int(f.read(1).hex(),16)
color_type = int(f.read(1).hex(),16)
comp_method = f.read(1)
filter_method = f.read(1)
interlace_method = f.read(1)
crc = f.read(1)
f.close()
print('signature---',signature)
print('length---',length)
print('c_type---',c_type)
print('i_width---',i_width)
print('i_height---',i_height)
print('bit_depth---',bit_depth)
print('color_type---',color_type)
print('comp_method---',comp_method)
print('filter_method---',filter_method)
print('interlace_method---',interlace_method)
print('crc---',crc)

…普通は、インデックス定義してforとかで回すんじゃないかな。…はい、すみませんやろうと思ったけど上手くいきませんでした。別に、本稿の目的はそこじゃないし。そもそもこのブログに目的なんてないし。
メモとしてはあれですね。i_width = int(f.read(4).hex(),16) かな。byte型(f.read(n))を16進数に直した(.hex())上で10進数整数型に変換(int(---))してます。今回ここにたどり着くのに結構ハマりました。…これももっと簡単なやり方あるのではないか、と思えてならない。なぜわざわざ10進数にしたかというと、100パー好みの問題です。

実行結果です。

signature--- b'\x89PNG\r\n\x1a\n'
length--- 13
c_type--- b'IHDR'
i_width--- 512
i_height--- 512
bit_depth--- 8
color_type--- 6
comp_method--- b'\x00'
filter_method--- b'\x00'
interlace_method--- b'\x00'
crc--- b'\xf4'

うん。よい感じ、としておきましょう。

最後になりましたが、本日読み出したIHDRチャンクの紹介。

  • Signature:ワタシPNGですよ、てことで、PNGファイルには絶対あるらしい。

  ーーーこの下はIHDRチャンクーーー

  • length:13固定。headerの長さのことかな
  • c_type:文字列'IHDR'が入っている。IHDRですよ目印。header捕まえたい時はこれを目印にサーチかけるんだろうな。
  • i_width:画像のサイズですね。我が家のlennaさんは512×512です。
  • i_height:同上
  • bit_depth:階調のことでしょう。8bitなので256階調かしら。
  • color_type:グレースケールとかトゥルーカラーとか。「6」ってなによ、と思って調べたら、「トゥルーカラー+アルファ画像」ですって。アルファ画像ってなんだ?
  • comp_method:圧縮方式。PNGは圧縮も扱えるんですね。今回は0なのであまり考えない。
  • filter_method:フィルター方式。同上
  • interlace_method:インターレース方式。同上
  • crc:「Cyclic Redundancy Check」のことです。通信における失敗検知のための信号。わざと冗長にしてうんたらかんたら。計算方法は知らん。

ということで、PNGのファイルヘッダーまで読みました。次はいよいよimageデータだ。画像処理っぽいことをやっていきたいぞ。