こんにちは。最近好きな食べ物は、焼肉と焼き鳥とラーメンとその他もろもろです。
画像とは
画像は、基本的に1ピクセルが下記のようにRGBのデータを持っています。
横3ピクセル・縦9ピクセルの真っ白な画像は、下記のように表すことができます。
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
PNGとJPEGの圧縮方法の違い
PNG
可逆圧縮という方式を採用しています(圧縮後も展開できる)
JPEGと比べると圧縮率は劣るものの、全てのピクセルがきちんと表示されるため、
イラストなどを綺麗に写すことができます。さらに、同じ色を使っているほど圧縮率が高いです。
JPEG
非可逆圧縮という方式を採用しており、PNGよりも基本的に圧縮率は高いです(圧縮後は展開できない)
不要なピクセルを自動的に排除して保存しているので、完全に元に戻すことはできません。
風景などの色が多いものは、JPEGにすると良いです。 PNGの圧縮方法
「1byteがなになにで」などの細かい説明は無視をして簡単に説明していきたいと思います。
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
まずは、できるだけ1や0といった同じような数字が増えるように、左側に0~4の値を割り振ります。
割り振る理由としては、公式の文章を読んだわけではないですが、同じ文字を増やしているのではないかと考えています。
後述する「Deflate」という圧縮手法は同じ値が多いほど圧縮率が高くなります。
・0の行は何もしない。
・1の行は、左側の1ピクセルと比較を行います。左側のピクセルがない場合は、rgb(0, 0, 0)とします。
・2の行は、真上の1ピクセルと比較を行います。真上のピクセルがない場合は、rgb(0, 0, 0)とします。
・3の行は、左側の1ピクセルと真上の1ピクセルの平均との差分を算出します。
・4の行は、1ピクセルの左隣、直上、左斜め上のピクセルの色からPaeth predictorという手法で選ばれた色との差分として保存されています。
※Paeth predictorが気になる方は、
https://www.w3.org/TR/PNG-Filters.htmlの6.6を見ていただければと思います。
0 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
1 |
255 |
255 |
255 |
0 |
0 |
0 |
0 |
0 |
0 |
2 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
3 |
128 |
128 |
128 |
0 |
0 |
0 |
0 |
0 |
0 |
3 |
128 |
128 |
128 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
255 |
255 |
255 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
255 |
255 |
255 |
0 |
0 |
0 |
0 |
0 |
0 |
3 |
128 |
128 |
128 |
0 |
0 |
0 |
0 |
0 |
0 |
2 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
値を割り振り終わったら、Deflateという圧縮手法で圧縮します。
Deflateは、LZSSというデータ圧縮アルゴリズムとハフマン符号という圧縮方法を組み合わせたものです。
ここは難しいのでざっくりと、同じ文字が多いほど圧縮率が高くなる圧縮手法と考えていただければと思います。
プログラマーは、NodeやPythonなどにもあるzlibという標準ライブラリを使用することで、簡単に圧縮と展開を試すことができます。
調べてみると結構面白いので、「LZSS とは」や「ハフマン符号 とは」と検索してみてはいかがでしょうか。