続コンピュータリテラシーはいかにして身につけるのか
今回はプログラマのS君の書いたプログラムの話だ。S君が書いたプログラムで出力がpng形式のファイルになっているはずなのだが、そのファイル、FAXビュアーでは正常に表示されるのに、別のソフトでは開けない。
おかしいなと思ってファイルサイズを見たら、どうもbmpファイルっぽいファイルサイズだ。バイナリエディタで開いてheaderを確認したらやはりbmpファイルだった。
bmpファイルは拡張子を偽ってもFAXビュアーやペイントでは開けるのだ。(Windows 7にて確認)
それで、どうしてpngで出力するはずがbmpになっているのかという話なのだが、彼のソースを見ると、
switch (Path.GetExtension(outputFilename).ToUpper() ) { case "PNG" : …
のように出力したいファイル名の拡張子ごとに分岐していた。これはこれでいいのだけど、Path.GetExtensionは".png"のようにピリオドも含めて返す。(「拡張子にはピリオドを含むのか?という話」→ http://d.hatena.ne.jp/yaneurao/20101123 )
まあ、それはそれでささいなミスと言えばささいなミスなんだけど、問題は、pngファイルとbmpファイルとではファイルサイズが全然違うのに何故気づかないのか?ということだ。
たぶん、S君は次のような問題に即答できないだろう。
問) 640×480のbmpファイル(無圧縮、フルカラー)のサイズはいくらか?概算でいいので答えよ。
答) bitmap headerが先頭に付与されているがそれは60バイト程度で十分に小さいので無視できる大きさだ。フルカラーなので1ピクセルが3バイト。
概算でいいので 640 → 600とみなして、480 → 500とみなそう。640×480 = 0.6K × 0.5K = 0.3Mピクセルあるわけだ。1ピクセルが3バイトなので3倍して0.9MB(900KB)。これがこの問題の答え。
つまり、pngファイルならbmpファイルの数分の1になっているはずで、640×480のpngファイルのファイルサイズが900KB前後であればそれは明らかにおかしい。
こういう感覚を普段から養っておく。100×100のbmpなら0.1K×0.1K×3 = 0.03MB(30KB) だし 1000×1000なら1K×1K×3 = 3MBみたいな感じ。そうすると拡張子がpngやjpgなのにbmp並のサイズであればすぐに気づく。いや、気づかなければおかしい。
しかし、私はS君同様、pngファイルを書きだしたつもりがbmpファイルを書きだしてしまっているプログラマを何人も見てきた。彼らはみなファイルサイズに無頓着なので、上の問題に即答できなかった。即答できないから、ファイルサイズが明らかにおかしくて正しいファイルを書き出せていなくとも気づかないのだ。
即答できない原因を考えてみるに、
1) フルカラーで1ピクセルが何バイトなのか理解していない
2) 画像ファイルが無圧縮なのか圧縮なのか理解していない
3) K×K = M を理解していない
4) bitmap headerが何バイト程度なのかを知らない
などが挙げられるが、1)〜4)を個別には理解していても、そこまで考えたことが無いという人がほとんどだろう。
いまどき、ライブラリなりなんなりでbmpファイルの内部構造を知らなくともbmpファイルを読み込んで画面に表示することはいともたやすくに出来るが、楽に出来るがゆえにプログラマとしての地力は急速に失われているんではないかと思ったりもするんだが。