実は『JPEGで保存』を繰り返しても大して劣化しない

GenerationLoss-400x300.png

Gunma.web #3のLT、4枚めのスライドで「このバチカンのJPEG画像を50,000回『JPEGで保存』すると、こんな風に劣化してしまいます」と言いました。

実のところ、あの画像を50,000回”単純に”繰り返しJPEG圧縮しても、あんな風に劣化しません。

テーマの本質ではなかったので、LTでは説明を省略しました。補足の意味でここに書いておきます。

これ、気づくのに少し時間がかかりました。

JPEG圧縮にはImagemagicのconvertを使用します。 資料作成時、はじめに書いたシェルスクリプトが以下。

cp ORG.JPG temp.jpg  
for i in {0..100}; do  
    convert temp.jpg -quality 90 $i.jpg  
    rm temp.jpg  
    cp $i.jpg temp.jpg  
done

これを実行すると、元の画像”ORG.JPG”が、圧縮率90%で100回繰り返しJPEG圧縮されるのですが、15回めから劣化しなくなります。

回数を増やそうが、圧縮率を変化させようが、ものの十数回で劣化が止まります。

最初、劣化の実験には適さない画像(色数や写真そのもの)なのかとか、convertの使い方に誤りがあるのかとか悩んでいたのですが、答えはWikipediaにありました。

http://en.wikipedia.org/wiki/File:JPEG_Generarion_Loss_rotating_90_(stitch_of_0,100,200,500,900,2000_times).png

この画像資料は、同じくWikipediaのGeneration loss
からリンクされているもので、JPEGを2,000回圧縮して劣化させるという、今回の目的そのままの画像です。

親切にもシェルスクリプトが載ってました。

or i in {0..2001}; do   
  
convert GenerationLoss_step$i.jpg -rotate 90 -quality 85 GenerationLoss_step$(($i+1)).jpg  
  
if [ $(($i%100)) -ne 0 ]; then  
 rm GenerationLoss_step$i.jpg  
fi  
  
echo -n "."  
  
done

「回転させていた」

このスクリプトでは、convertの”rotate”パラメータにより90度ずつ回転させながら圧縮しています。 未だJPEG圧縮のアルゴリズムを完全に理解しているわけではないのですが、同じアルゴリズムを用いる限り、一定回数に達すると「情報の間引き」に効果がなくなってしまうようです。

画像を回転させることで、各々のピクセルの位置が変化し、再び”新たに”間引かれるという効果が生まれます。 JPEG圧縮アルゴリズムについては、こちらのコンテンツを参照しました。丁寧に書かれています。

http://www.marguerite.jp/Nihongo/Labo/Image/JPEG.html

http://www.amazon.co.jp/exec/obidos/ASIN/4274079171/ivory-social-22/