前回、pngファイルのSignatureとHeaderを読み出したわけです。なんかダラダラと変なコードを書いてしまいました。とはいえもっとスマートにするためにはどうしたら良いのかよくわかりません。暗黙のルール的なものもきっとあることと想像しますが、まったく気にせず思いつきでやってます。
で、本日も思いつき案件なのですが、せっかくpythonで書いているのだし、自分でクラスを定義してみようと思います。やり方として正しいのかは分かりませんが、今後imageデータを触って行く際にコードが分かりやすくなりそうな気がします。
具体的には、ファイルパスを渡して、クラス内で定義された関数でSignature,画像サイズを返してもらいます。
class png_img: def __init__(self,fname): self.f = open(fname,'rb') self.signature = self.f.read(8) self.length = int(self.f.read(4).hex(),16) self.c_type = self.f.read(4) self.i_width = int(self.f.read(4).hex(),16) self.i_height = int(self.f.read(4).hex(),16) self.bit_depth = int(self.f.read(1).hex(),16) self.color_type = int(self.f.read(1).hex(),16) self.comp_method = self.f.read(1) self.filter_method = self.f.read(1) self.interlace_method = self.f.read(1) self.crc = self.f.read(1) self.f.close() def getSignature(self): return self.signature def getWidth(self): return self.i_width def getHeight(self): return self.i_height name='/フルパス/lenna.png' png=png_img(name) print(png.getSignature()) print(png.getWidth()) print(png.getHeight())
オブジェクト指向言語っぽくなってまいりました。ウットリ…。
高級な言語で低レベル処理をすることのワクワク感、わかっていただける方ってどれくらいいるのでしょうか。
実行結果です。
b'\x89PNG\r\n\x1a\n' 512 512
やってみてのトピックスメモメモ。
- コンストラクタ(初期化ユニットのようなもの)は
__init(self,)__
で定義する - クラス内関数の第一引数はself、すなわち自分自身。呼び出し側(上のコードでは
print(png.getSignature())
など)で何も書かなくても第一引数はselfになる - クラス内で関数定義する時は第一引数にselfって書かないと、実行時に、引数の数不一致ですよ、と言われる ←これハマった!
本当は、例外処理とか定義してダメな時はエラーで返すようにすべきですが、自己満足のお勉強コードにそこまで凝ったことはしません。
あとは、class書いてるファイルを別ファイルにして、import png_proc
とかにしてしまいたいな。どうやるんだろう?
いろんな関数を追加していきたいところですが、うーむ、ちょっとあれですね。そろそろ書籍が欲しくなってきたな…。まあでもトライアンドエラーでやっていくのも楽しいから急がなくても良いか…。
はたして画像処理っぽい処理ができるのはいつになることやら。