私は先に進み、何が起こっているのか理解できるかどうかを確かめるために実験を繰り返しました。
手順
GIMPの「ソリッドノイズ」フィルター(フィルター>レンダリング>クラウド>ソリッドノイズ...)を使用して、デフォルト設定(以下に示す)を使用して、ランダムな256 x 256ピクセルのRGBイメージを生成しました。
そして結果:
次に、デフォルト設定を使用して、画像をJPEGとして保存しました。
次に、画像をWindowsに転送し、ファイルエクスプローラーで画像を右クリックし、メニューから[ プレビュー ] を選択して、Windowsフォトビューアーで画像を開きました。次に、下のボタンを使用して画像を回転し、矢印キーを使用して次の画像に移動して画像を保存しました。
以下の各テストでは、元の画像のコピーから始め、対応する回数だけ回転(回転ボタンをクリック)してから保存しました。以下に、サイズ変更(ls -l -r
)を示します。
size in bytes last-modified date
VVVVV VVVVV
-rwxrwx--- 1 root vboxsf 6258 Nov 8 11:24 original.jpg
-rwxrwx--- 1 root vboxsf 23645 Nov 8 11:30 cw.jpg
-rwxrwx--- 1 root vboxsf 23636 Nov 8 11:30 cw-cw.jpg
-rwxrwx--- 1 root vboxsf 23649 Nov 8 11:30 cw-cw-cw.jpg
-rwxrwx--- 1 root vboxsf 6258 Nov 8 11:27 cw-cw-cw-cw.jpg
-rwxrwx--- 1 root vboxsf 23649 Nov 8 11:31 cw-cw-cw-cw-cw.jpg
-rwxrwx--- 1 root vboxsf 23649 Nov 8 11:29 ccw.jpg
-rwxrwx--- 1 root vboxsf 23636 Nov 8 11:29 ccw-ccw.jpg
-rwxrwx--- 1 root vboxsf 23645 Nov 8 11:29 ccw-ccw-ccw.jpg
-rwxrwx--- 1 root vboxsf 6258 Nov 8 11:27 ccw-ccw-ccw-ccw.jpg
-rwxrwx--- 1 root vboxsf 23649 Nov 8 11:30 ccw-ccw-ccw-ccw-ccw.jpg
即時観察
- Windows Photo Viewer(WPV)はサイズを劇的に増加させます。このテストの増加量は約4倍です!
- すべての新しい画像はほぼ同じサイズに増加しますが、同一ではありません。
- WPVは、画像を360度の倍数で回転させても、再エンコードしたり、保存したりすることはありません。(タイムスタンプ11:27は、ファイルが最初にコピーされたときです。)
cmp -l
同一のコンテンツを持つファイルを使用すると、ファイルの違いを確認できます。
robert@unity ../jpeg-rotate-test % cmp -l cw.jpg ccw-ccw-ccw.jpg
2223 63 62
2224 60 71
2226 60 64
2227 60 66
robert@unity ../jpeg-rotate-test % cmp -l cw-cw.jpg ccw-ccw.jpg
2223 63 62
2224 60 71
2226 60 64
2227 62 64
robert@unity ..jpeg-rotate-test % cmp -l ccw.jpg cw-cw-cw.jpg
2223 62 63
2224 71 60
2226 64 60
2227 61 64
robert@unity ../jpeg-rotate-test % cmp -l cw.jpg cw-cw-cw-cw-cw.jpg
2221 60 61
2223 63 61
2224 60 66
2226 60 61
2227 60 61
robert@unity ../jpeg-rotate-test % cmp -l ccw.jpg ccw-ccw-ccw-ccw-ccw.jpg
2223 62 63
2224 71 60
2226 64 65
2227 61 64
これらのファイルの違いは4バイト(実際にはタイムスタンプ)だけです。つまり、WPVは毎回同じことをしています。今は、それが何であるかを把握するだけです。
詳細な観察
このために、私はJPEGsnoopを使用して、画像内の正確な内容を確認しました。
出力はかなり長いので、要点としてそれらにリンクしました。違いの概要は次のとおりです。
GIMPは、メタデータにAPP0
(JFIF)およびCOM
(コメント)セグメントのみを使用します。WPVはAPP0
セグメントを変更せずに残しますが、不思議なことにコメントにヌルバイトを追加します(そのため、ヌルで終了します)。
WPVはAPP1
、ExifとXMPメタデータの2つのセグメントを追加します。これらのセグメントは、それぞれ4286バイトと12726バイトです。これらを合わせると、ファイルサイズの増加全体のほぼ全体を占めています。
GIMPはプログレッシブJPEGを生成し、WPVはベースライン(非プログレッシブ)JPEGを生成します。このため、GIMPの画像には複数のスキャンセグメントがありますが、WPV画像には1つしかありません。私の経験では、プログレッシブ画像は時々わずかに小さくなります。
GIMPは1×1のクロマサブサンプリングを使用し、WPVは2×2のサブサンプリングを使用しました。これは、何らかの理由でこれが白黒画像であることを検出できない限り、WPVが「真の」ロスレス回転を使用していないと考えるようになります。
これらの問題を解決するために、2回目のテストを実行しました。
手順
最初のテストと同様の手順に従いました。次の設定で、RGBノイズフィルター(フィルター>鼻> RGB鼻...)を使用して、ランダムな256×256 RGBイメージを作成しました。
結果は次のとおりです。
次の設定を使用して、ファイルをJPEGとしてエクスポートしました。
プログレッシブはオフになっているが、サブサンプリングは依然として4に設定されている:4:4(1×1サブサンプリングするための別の名前です)。品質は98に向上します。
画像をコピーし、時計回りにコピーを回転させました。次に、回転したバージョンをコピーし、そのコピーを反時計回りに回転させたため、元のコピーとWPVで処理されたコピーの品質を直接比較できます。
結果
-rwxrwx--- 1 root vboxsf 159774 Nov 8 16:21 original-random.jpg
-rwxrwx--- 1 root vboxsf 222404 Nov 8 16:24 cw-random.jpg
-rwxrwx--- 1 root vboxsf 222467 Nov 8 16:24 cw-ccw-random.jpg
今回の増加は相対的な観点では小さくなりますが(約40%)、絶対的な増加はさらに大きくなり、約62 kBになります。これは、WMVが効率の低いエンコードを使用していることを示唆しています。
ImageMagickを使用して、2つの画像を比較します。
robert@unity ../jpeg-rotate-test % compare -verbose -metric AE original-random.jpg cw-ccw-random.jpg null:
original-random.jpg JPEG 256x256 256x256+0+0 8-bit sRGB 160KB 0.000u 0:00.009
cw-ccw-random.jpg JPEG 256x256 256x256+0+0 8-bit sRGB 222KB 0.010u 0:00.010
Image: original-random.jpg
Channel distortion: AE
red: 0
green: 0
blue: 0
all: 0
original-random.jpg=> JPEG 256x256 256x256+0+0 8-bit sRGB 0.050u 0:00.020
元のコピーと回転したコピーの間にゼロピクセルの違いがあります。そのため、WPVが「真の」ロスレスローテーションを使用していない場合でも、十分な仕事をしています。私は何が起こっているかを知っていると思うので、説明するために、JPEG圧縮の背後にある数学に少し流用します。
JPEG圧縮アルゴリズムは、画像を8×8ピクセルのブロックに分割します。次に、これらの各ブロックは離散コサイン変換(DCT)にかけられます。結果のDCT係数は、ブロックを異なる周波数の波の合計として記述します。次に、アルゴリズムは、ノイズと非常に小さな詳細に対応する高周波の情報を「破棄」します。デコードプロセスはDCTを反転し、保存された波形を加算してブロックを取り戻します。
実際に変換を元に戻したりやり直したりすることなく、DCT「波」を回転させることができます(基本的に、すべての水平波を垂直波に、またはその逆に変換します)。WPVで起こると思うのは、画像が実際にデコードされ、回転され、その後再エンコードされるということです。再エンコード処理中、画像のサイズは両次元で8の倍数であるため、新しいブロックはそれぞれ元のブロックの1つに対応します。重要なのは、各ブロックに高周波数成分がないため、アルゴリズムは情報を破棄せず、「真の」ロスレス回転が持つ正確なDCT成分を正確に見つけます。
最後に、JPEGファイルのコンポーネントをもう一度見ていきます。結果は要旨として再びリンクされます。2つの比較:
WPVイメージには、追加の4286 + 2バイトのExifメタデータ、コメント内の1つの追加バイト、および12,726 + 2バイトのXMPメタデータが含まれます。これは、合計17,017バイトの追加メタデータです。そのデータはすべて何に使用されますか?信頼できる16進エディターと関連する標準のコピーを使用して、ファイルを覗き込みました。
Exifメタデータは、多数のタグを含むTIFFイメージのように構成されています(さらに複雑な方法がありますが、ここではスキップします)。Exifセグメントのほとんどのバイトは、タグ番号EA1C
(10進数で59,932)を持つ2つの同じタグに含まれています。そのタグ番号は、私が見つけることができるどこにも文書化されていません。両方のタグには、2060バイトの「未定義」タイプが含まれます。これは、最初の6つ(1C EA 00 00 00 08
)を除くすべてヌルバイトです。これらのタグが何であるのか、なぜ2つあるのか、それぞれ2 KBである必要があるのかはわかりません。
XMPメタデータは、実際には名前空間と長いUUIDを含む埋め込みXMLドキュメント全体であり、WPVバージョン文字列(Exifメタデータに既に存在する)のみが含まれています。ただし、それは約400バイトしか占めていません。セグメントの残りは、100個のスペースの122回の繰り返しとそれに続く改行です。これは、12,000バイトを超える完全に無駄なスペースです。
前のテストと同様に、GIMPとWPVの両方で同じDCT量子化テーブルが使用されます。これは、正確に同じDCT係数を計算する必要があることを意味します。これが、画像がまったく同じである理由です。WPVがたまたま同じ量子化テーブルを使用しているのか、それとも入力からテーブルをコピーするのかはわかりません。
前のテストとは異なり、今回はWPVが1x1サブサンプリングを使用するため、これがカラーイメージであることを実際に検出している可能性があります(または、イメージを可逆的に再エンコードするには少なくともより高いサンプルが必要です)。
GIMPとWPVは、異なるハフマンテーブル(エントロピーコーディングステップの一部)を使用します。WPVのテーブルは合計279バイト大きくなり、ある場合には7倍のコードが含まれます。
JPEGsnoopの統計を見ると、これらのコードの一部がほとんど使用されていないことがわかります。たとえば、ID: 1, Class: AC
定義されている119個の16ビットコードのうち、実際に使用されているのは23個のみです。全体として、実際のスキャンセグメントはWPVバージョンで28.5%大きくなります。
概要
バージョン情報:
OS(Linux)(uname -a
):
Linux unity 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1+deb8u1 (2016-09-03) x86_64 GNU/Linux
OS(Windows):
GIMP(Linux):2.8.14(パッケージgimp
、バージョンから2.8.14-1+deb8u1
)
ウィンドウフォトビューアー(画像メタデータによる):
Microsoft Windows Photo Viewer 10.0.10586.0