あけましておめでとうございます.今年は大変な…人生の行き先を分ける年になりそうです…
いつかファイルのフォーマットを直接触ることをやりたかったので,今年の書き初めはこれにしました.最初はJPEGと思っていたのですが,だいぶめんどくさそうだったので3分で諦めました.不可逆圧縮は難しいですね.
JPEGのEXIFビューアもいいなと思いましたが,それは巷にいくらでもあるので,とりあえずなんとなくPNGの構造について調べることにしました.簡単に調べてみたところ,割と周辺情報のメタデータ(チャンク)は表示しやすそうだったので,それを表示するものを作ってみました.
IHDR,bKGD,tIME,pHYs,gAMAのデータ表示と,CRC32の検証機能がついています.CRCはチャンクタイプフィールドもCRCにかけると思っていなくて,そこで時間かかりました.仕様書はしっかり読まないとダメですね.デモコードはPython3でのみ正常に動きます
とりあえずこれを作ったのですが,やっぱり自分でエンコーダを作ってこれで検証したい欲が出てきたので,簡単なモノクロ2階調で画像を生成するエンコーダを書きました.色々慣れてなくて,だいぶ冗長でカオスです.目標はアイコンを自作エンコーダで作ることにしました.
Pythonで(というか,プログラミングで)ビット列を扱ったのは初めてだったので,どうやればいいのかだいぶ戸惑いました.まず,Cの構造体みたいに組み上げるのにはstructというものを使います.まんまですね.
“00CFAA”みたいな文字列をcodecs.decode(data,’hex’)にかけるとb’\x00\xcf\xaa’って出てくるのは便利.文字列長が奇数だとbinascii.Error: decoding with ‘hex’ codec failed (Error: Odd-length string)って怒られるので注意.なぜ…
[b’H’, b’O’, b’G’, b’E’]を結合するとき,b”.join(list)ってやるとできるのも知らなかった.bytesでもできるんだね.
標準ライブラリ外では,bitstringっていうものもあると教えていただきました.今回は標準ライブラリでもいけそうなので,使いませんでした.
大変かと思っていましたが,低圧縮率でいいならzlibで各列を圧縮したら一発なので,だいぶ簡単でした.下のがこのコードで生成される画像.
でも,やっぱりカラーも作りたいので,ちょっと改良して,各色が色深度8bit(256階調^3色=16777216色)の画像を生成するものを作りました.各色8bitなのは,16進2文字でちょうど一色なので都合よかったからです.そのへんでもちょっと混乱しました.
コード見ると解ると思いますが,ロジック部分はめちゃくちゃシンプル.
というわけで,faviconみたいなものが作れました.めでたい.
あと,ランダムに出力するようにしたらこんな感じのおしゃれっぽいものが作れました.
いい書き初めでした.