後ろを向いて後退します

これって前に進んでいることになりませんか?

PNG, QoL - Aizu AdC 2015

Aizu AdC 2015

この記事はAizu Advent Calendar 2015の23日目として書かれました。

www.adventar.org

前の人はabout_hiroppyさん、次の人は__Himajinさんです。

はじめてのAdvent Calender

Michaelです。

twitter.com

AdventCalender初参加なのに遅刻しました。

アドベントカレンダー - Wikipedia

技術系の話にしようかそれ以外の話にしようか迷ったんですけど、内容的な問題で片方だけの記事を書こうとするとかなり薄っぺらくなっちゃいそうだったので両方書きます。

もくじ

QoLを上げる話

QoL(Quality of Life)

クオリティ・オブ・ライフ - Wikipedia

私、一人暮らしを初めてもうすぐ2年になります。

快適で効率的な日常生活を送る上で、「これあると便利/良い」と感じたものを個人的な感想も交えて紹介したいと思います。

キッチンハイター

キッチンハイター 台所用漂白剤 特大サイズ 2500ml

キッチンハイター 台所用漂白剤 特大サイズ 2500ml

キッチン周りや洗面所など、大体の汚れや臭いはコレの原液ぶっかけて15分ほど放置すれば殲滅できます。

塩素系の漂白剤なので取り扱いには注意。

キッチンペーパー

日清紡 ピーチ キッチンタオル 8ロール

日清紡 ピーチ キッチンタオル 8ロール

一人暮らしをする上で誰もが面倒に思ってしまうことの一つとして洗濯・食器洗いがありますよね。

このキッチンペーパー(キッチンタオル)があれば雑巾や台拭き、食器拭きなど全部に代用が利いてしまうので毎回毎回細かいタオルや雑巾類を洗濯して干す手間も省けるのです。

使い回しをしないことによる衛生面での安心感があるのも強さの一つ。

ウェットティッシュ

エリエール 除菌できるアルコールタオル 本体 100枚入り

エリエール 除菌できるアルコールタオル 本体 100枚入り

アルコールや次亜塩素酸ナトリウム、ただの水など色々なものを染み込ませたウェットティッシュがありますが、私はアルコールのものをよく使っています。

細かい汚れなんかをチョイチョイと落としたいときには重宝しますね。

キッチン周りの油汚れなどもコレを使えば割と楽に落とせると思います。

紙皿

料理をしていると、「あ、これ一度別のところに置いておきたい」なんてことがたくさんありますよね。

わざわざ新しい皿やボウルを出して洗い物を増やそうとせずに、使い捨てのお皿を使ってしまえばいくらか後片付けが楽になるのでは?

紙皿や紙ボウルはパーティーや多人数での自炊などでよく使われるようなイメージがありますが、ぼっちでも十分に使える便利グッズの一つであると思います。

髭剃り

シック クアトロ5 チタニウムホルダー 替刃2コ付

シック クアトロ5 チタニウムホルダー 替刃2コ付

私は髭が濃くて伸びるのも早いので毎日のように髭を剃っているのですが、最近実感しているのは「やっぱり使い捨ての髭剃りよりもブレード交換式の高い髭剃りのほうが気持ちよく剃れるな」ということ。

個人的なオススメは「シック Quattro 5」と「シック ハイドロ スキンディフェンス シェービングジェルフォーム」です。

肌を傷めずに深剃りできることの気持ちよさを皆さんにも是非体験していただきたいですね。

防水スピーカー

防水のBluetoothアクティブスピーカーです。

小さいボディですが、360度に広がる綺麗な音、少なくない低音には満足させられました。

お風呂でも浸水を気にせず使えることが非常につよい。(長時間沈めた場合は防水は保証できないらしいですが…)

安心と信頼のSONY製です。

お香

お香 コーン 12個セット

お香 コーン 12個セット

スティックタイプとかコーンタイプとか色々ありますが、コーンタイプはスペースをあまり取らないのでオススメです。

部屋に変な臭いがついたときの消臭目的もありますが、何より心をリラックスさせてくれるのが大きいと思います。

ただ、一度にたくさん焚きすぎるとお香の煙に火災報知器が反応する恐れがあるので注意が必要です。

快適性はお金で買う

これらのアイテムを使うようになってから、かなりストレスフリーな生活を送れるようになった気がします。(気のせいかも)

特に上記のうちで消耗品の類なんかはドラッグストアなどでも安く手に入ると思いますので、お財布もそれほど圧迫しないはずです。

ぜひ試してみてはいかがでしょうか。

PNGバイナリを読む話

本題です。

実はこの話題は前回のALT#0x04で話したネタの焼き直しみたいな感じなんですけど、他に何も無かったので許してください。

atnd.org

今回は入門の更に入門みたいな感じなのでそんなに深く掘り下げるつもりはありません。

1.どうしてPNGバイナリを読むの?

JPEGとかGIFとかでも良かったんですけど、PNGバイナリは構造が単純で読みやすいよという話を耳にしたので「んじゃ俺でも読めるんじゃね!?」って思って手をつけました。

JPEG - Wikipedia

Graphics Interchange Format - Wikipedia

2.PNG is 何

3.とりあえずバイナリエディタで見てみる

pixiaを使って、サイズ1×1の黒(#000000)で塗り潰した透過無しのPNGを作成してBZで開いてみました。

Pixiaホームページ

Binary Editor BZ - 窓の杜ライブラリ

f:id:mic_psm:20161013034801p:plain

※上のスクリーンショットはチャンクが分かりやすくなるように色分けしてあります。

簡単...?

4.signatureとcritical chunks

PNGを構成する上でそれぞれ必ず1つ必要になる部分です。(ただし、IDATチャンクに関しては1つのファイル内において複数の存在が許されています。)

critical chunksには3+1種類あり、上のPNG画像はsignature含めてちょうどそれらのみで構成されていました。

4.1.signature

0(0x0) to 7(0x7) bytes

0x89504E470D0A1A0A

ファイルがPNGであるということを識別するコードであり、全てのPNGファイルにおいて共通です。

4.2.chunks

critical chunksを含む、PNGを構成する全てのチャンクは以下の4つのブロックからなる構造を持っています。

 data length   name   chunk data   CRC 
4 bytes 4 bytes x bytes 4 bytes

data length - chunk data部の長さ(単位:byte)を16進数で保持しています。

name - チャンク自身の名称を表します。

chunk data - チャンクのデータそのものを表します。

CRC(CRC32) - nameとchunk dataのビットに関するCRC32符号(計算方法についてはIHDRの項で後述)。

4.3.critical chunks

PNGの構成に必須な3+1種類のチャンクの総称です。IHDR、IDAT、IEND、PLTEがありますが、PLTEチャンクに関しては存在は任意とされてるので3+1という表現を用いました。

以下の4.3.*の項で、上の画像を構成する各critical chunksを先頭から順に見ていきます。

4.3.1.IHDR

8(0x8) to 32(0x20) bytes ※IHDRは25 bytes固定

  • data length - 0x0000000D つまり13
  • name - 0x49484452 ASCII文字で"IHDR"
  • chunk data - 0x00000001 00000001 08 02 00 00 00
    先頭から順に幅 1px、高さ 1px、ビット深度 8bits、カラータイプ 2(=RGB)、圧縮方法 0、フィルター方式 0、インターレース方式 0(=非インターレース)
    • 圧縮方法、フィルター方式については今のところ0のみが定義されています。
    • カラータイプがRGB、ビット深度が8 (28=256) なので1ピクセルあたり赤緑青各色256段階の濃度で色を表現していることになります。
  • CRC - 0x907753DE
4.3.1-a.IHDRのCRC32の計算

0x4948445200000001000000010802000000

これのCRC32を計算すればいいわけですね。

pythonを使ってみます。

$ python
Python 2.7.9 (default, Mar  1 2015, 12:57:24) 
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> import binascii
>>> s = (chr(0x49)+chr(0x48)+chr(0x44)+chr(0x52)+chr(0x00)+chr(0x00)+chr(0x00)+chr(0x01)+chr(0x00)+chr(0x00)+chr(0x00)+chr(0x01)+chr(0x08)+chr(0x02)+chr(0x00)+chr(0x00)+chr(0x00))
>>> c = binascii.crc32(s)
>>> print c
-1871227938

あっ、10進数表示…。

webの変換ツールを用いて16進数に変換したら、

f:id:mic_psm:20161013034925p:plain

90 77 53 DE

ゴリ押しですけどどうやらできたみたいです。python便利。

4.3.2.IDAT

33(0x21) to 56(0x38) bytes

  • data length - 0x0000000C つまり12
  • name - 0x49444154 ASCII文字で"IDAT"
  • chunk data - 0x08D763606060000000040001
    Deflateを用いてエンコードされた画像のピクセル情報
  • CRC - 0x2734270A
4.3.3.IEND

57(0x39) to 68(0x44) bytes ※IENDは12 bytes固定

  • data length - 0x00000000 IENDチャンクはlengthは0で固定
  • name - 0x49454E44 ASCII文字で"IEND"
  • chunk data - 無し
  • CRC - 0xAE426082

CRCはnameとchunk dataから求められるので、全てのPNG画像においてIENDのCRCは一意に決まる(つまりIENDチャンクも一意に決まる)ということになります。

4.3.4.PLTE

今回のバイナリには存在しませんが、構造だけ解説します。

  • data length - 3×n+12 bytes
  • name - 0x504C5445 ASCII文字で"PLTE"
  • chunk data - ex) 0xFF0000 00FF000 000FF
    最大で256個のパレットエントリを持ち、各パレットエントリにつき赤緑青各色ビット深度8で 3 bytes、合計で 3×n bytes(n≦256) の大きさの色情報を持つ
    この例のPLTEチャンクは純粋な赤色(#FF0000)緑色(#00FF00)青色(#0000FF)のパレットエントリを持っていることになる
  • CRC - 他のチャンクと同様の方法で求められる

5.人力でPNGを構成できるのか?

頑張れば可能かもしれません。

ancillary chunks(補助チャンク, 今回は解説しません)については少し構成が難しくなってしまうかもしれませんが、critical chunksのIDATなどについてはpythonなどを用いれば可能な気がします。

6.summary

割とヒューマンフレンドリーなバイナリで、「なんじゃコレわけ分からん」っていう箇所が無かったのはとても感心しました。画像自体が限りなく単純だったせいもあるのかもしれませんが…。

初めてのAdvent Calenderだったのですが、訳あって手をつけるのがかなり遅くなってしまって完成度も低い記事になってしまったことをお詫びします。

この記事についてですが実は続きを書こうと考えておりまして、今作ろうと試行錯誤している「簡易文字列画像ジェネレータ(入力文字列を背景透過PNGとして出力するプログラム)」についていろいろお話できたらなと思っている次第であります。

今回解説しなかったancillary chunks(補助チャンク)についても次回の記事で一緒に解説したいと思っています。