アプリ開発日誌
2021.11.05
データが大きいファイルを圧縮してみよう
パソコンを使っている皆さん、この圧縮ファイル「.zip とか .rar」などはみたことあるでしょうか?
通信する時や保存する時など、スペースを勿体無いの為、データを圧縮することが使われています。
しかし、パソコンはどうやってデータを圧縮するかは疑問に思ったことはありますか?
本日、データを圧縮することは簡単に説明いただきます。
データを圧縮することは大きく2種に分けています。非可逆圧縮(Lossy)と可逆圧縮(Lossless)です
非可逆圧縮(Lossy)
デジタル画像が一般的になるにつれて、1990年代初頭、不可逆圧縮方式が広く使用されるようになりました。 これらのスキームでは、不要な詳細を削除するとストレージスペースを節約できるため、情報の損失が許容されます。 情報の保存とサイズの縮小の間には、対応するトレードオフがあります。 非可逆データ圧縮スキームは、問題のデータを人々がどのように認識するかに関する調査によって設計されています。 たとえば、人間の目は、色の変化よりも輝度の微妙な変化に敏感です。 JPEG画像圧縮は、情報の不要なビットを四捨五入することによって部分的に機能します。 音声の音響心理学や画像やビデオの心理視覚など、多くの一般的な圧縮形式がこれらの知覚の違いを利用しています。
可逆圧縮(Lossless)
可逆圧縮アルゴリズムは通常、統計的冗長性を利用して、情報を失うことなくデータを表すため、プロセスを元に戻すことができます。 ほとんどの実世界のデータは統計的な冗長性を示すため、可逆圧縮が可能です。 たとえば、画像に数ピクセルにわたって変化しない色の領域がある場合があります。 「赤ピクセル、赤ピクセル、…」をコーディングする代わりに、データを「279赤ピクセル」としてエンコードすることができます。 これは、ランレングスエンコーディングの基本的な例です。 冗長性を排除することによってファイルサイズを削減するための多くのスキームがあります。
この下、簡単に文書を可逆圧縮することの例です。圧縮をしてみよう!!
例として僕の好きな曲の歌詞を使います。
「Eric ClaptonのTears In Heaven」ぜひ、聴いてみてください。^_^
*見やすいようにintの数字なら<>の中に入りれて、青い文字位します。
Would you know my name if I saw you in heaven?
Would it be the same if I saw you in heaven?
I must be strong and carry on
Cause I know I don’t belong
Here in heaven
Would you hold my hand if I saw you in heaven?
Would you help me stand if I saw you in heaven?
I’ll find my way through night and day
Cause I know I just can’t stay
Here in heaven
全部345bytesとなります。
簡単な方法1:辞書
この歌詞はよく見ると「heaven」と「Would」は結構使っていますよね!
String(heaven)の代わりにint(1)に書いて、そして「1-heaven」を入れます。
String(Would)もint(2)にしましょう。そして「2-Would」を入れます。
<2> you know my name if I saw you in <1>?
<2> it be the same if I saw you in <1>?
I must be strong and carry on
Cause I know I don’t belong
Here in <1>
<2> you hold my hand if I saw you in <1>?
<2> you help me stand if I saw you in <1>?
I’ll find my way through night and day
Cause I know I just can’t stay
Here in <1>
<1>-heaven
<2>-Would
オリジナルは345bytes、圧縮したら316bytesとなります。
簡単な方法2:LZWアルゴリズム (基本はもっと複雑ですが、今回は簡単なバージョンで)
この方法を理解できるため、ASCII Binaryテーブルが必要です。
上のテーブルの参考で
8桁の数字 = 8bits = 1byte
h => 01101000(サイズは 1byte)
heaven => 01101000 01100101 01100001 01110110 01100101 01101110(サイズは 6byte)
Would => 01010111 01101111 01110101 01101100 01100100 (サイズは 5byte)
歌詞の1行目2行目を見ましょう
1行目
Would you know my name if I saw you in heaven?
2行目の時、Wouldとheavenは見たことありますね〜 代わりに<i,j>で書きます。
i = 逆算する文字数
j = コピーする文字数
じゃ、前から参考で書きしましょう
<47,5> it be the same if I saw you in <45,6>?
<47,5>とは今の時点から47文字前、5文字をコピーすることです。
数えて47文字前は1行目の「Would」なのです。
<45,6>も今の時点から45文字前、6文字をコピーすることです。
数えて45文字前は1行目の「heaven」なのです。
Byteで見ると、Would=5byte から int2たつで 47 5 = 2byteとなります。
これでサイズを減ることができます。前半のWouldとheavenだけ圧縮で書くと
Would you know my name if I saw you in heaven?
<47,5> it be the same if I saw you in <45,6>?
I must be strong and carry on
Cause I know I don’t belong
Here in <119,6>
オリジナルの前半は164byte
圧縮したの前半は153byte
だいぶ減ることができます。
本当のLZWアルゴリズムを使ったらもっとスマートなので、オリジナル345bytesから228byteくらいまでが減ることができます。
参考のオンライン圧縮はこの下のLinkです。ぜひ、遊んでみてください。