画像がロスレスで回転している場合、なぜファイルサイズが変わるのですか?


37

私はロスレス画像回転の方法を探していましたが、それをかなりうまく説明するこの質問に遭遇しました:

「Windows Photo Viewer」の回転は無損失ですか?

そこで、ランダムピクセル(Photoshopクラウドフィルター)で256×256 JPEGを作成し、Windows Picture Viewerを使用して回転させました。回転後、ファイルサイズは実際に増加しましたが、最初の回転でのみ増加しました。その後のローテーションごとに、ファイルサイズは静的なままでした。20回回転した257×257の画像は非常に損失が大きくなりましたが、品質を著しく損なうことなく複数回回転したため、ロスレスで回転していることがわかります。


8
テストでファイルサイズはどのくらい増加しましたか?
ジェームズスネル

3
@JamesSnell私はそれを含めるべきだと知っていました。GIMPの差分クラウドフィルターを使用して行ったのは元々14,583バイトでしたが、ローテーション後に23,638バイトに変更されました。これは9000バイトを超える違いであり、メタデータだけを詳しく調べている場合、多くの追加データのように見えます。
振動クレチン

4
それは多くの追加メタデータのようです。その追加データのすべてがメタデータであると仮定するのは速すぎません。メタデータによるサイズの違いはほぼ一定である必要があるように思えます(いくつかの数値の文字列表現を考慮して、数バイト以内に)。
-scottbb

4
質問と密接な関係がある追加情報を提供する場合は、コメントではなく質問に編集してください。コメントは一時的なものであり、時々整理されます。
scottbb

2
テストイメージの元のバージョンをアップロードすると便利です。
CodesInChaos

回答:


36

これはおそらく、画像データがそのサイズを縮小するために量子化された後のJPEG圧縮の最終的なロスレスステージであるエントロピーコーディングによって引き起こされます。

JPEG画像を可逆的に回転させる場合、この最終的な可逆符号化レイヤーを元に戻し、アンパックされたDCT係数をシャッフルし、シャッフルされた係数を再度エントロピーコーディングする必要があります。エントロピーコーディングレイヤーの効率は、各ブロック内のDCT係数の順序に依存するため、画像を回転させると変化するため、回転後の画像ファイルが元の画像ファイルよりも数パーセント小さい場合も大きい場合もあります。

エントロピーコーディング手順を実行できる方法もいくつかあります。そのため、まったく同じJPEGイメージのファイルサイズは、エンコードを行うソフトウェアによって異なる可能性があります。エンコーダーの潜在的な違いには次のものがあります。

  • 算術エンコーディングの選択(まれですが、潜在的にはより効率的で、かつて特許取得済みでした)vs.ハフマンエンコーディング(よりシンプルで標準)
  • 連続(各8x8ピクセルブロックは一度に1つずつエンコード)対プログレッシブ(すべてのブロックの低周波数成分は高周波数成分の前にエンコードされ、通常わずかにコンパクト)エンコード順序の選択。
  • 標準のハフマンシンボルテーブルを使用する選択(高速でシンプル、非常に小さな画像の場合はより効率的)vs各画像に最適化されたカスタムテーブル(通常は大きな画像の場合はより効率的で、エンコードは低速で複雑)
  • カスタムハフマンテーブルを使用する場合、異なるエンコーダーが同じ画像データに対して異なるテーブルを生成する可能性があります。
  • データストリームにリスタートマーカーを含めるかどうか、いつ含めるかなど、エンコードプロセス自体のさまざまな低レベルの詳細もエンコーダーによって異なります。

また、通常作業する「JPEGファイル」には、実際にJFIFまたはExifコンテナにラップされたJPEG圧縮画像データが含まれています。画像を回転させるソフトウェアが実際にJFIF / Exifメタデータに実質的な変更を加えない場合でも、単にデータを再配置すると、ファイルサイズに数バイトの影響を与える可能性があります。

特に、JFIF / Exifメタデータにはフルサイズの画像のサムネイルが1つ以上含まれている場合があり、画像を回転させるソフトウェアは、サムネイルを再生成(またはロスレスで回転)する必要があります。サイズ画像。これだけでも、観測されたサイズの違いを簡単に説明できます。


4
9KB(60%)の差がある場合、私の推測ではサムネイルです。
BlueRaja-ダニーPflughoeft

JPEGはこれではエンコーダーとしては価値がありませんが、x264のようなビデオエンコーダーは、レートと歪みのトレードオフを決定するときに、エントリーコーダーが次に出力するものをエンコードする能力を実際に考慮することができます。(つまり、各代替にかかるビット数を決定し、それを不可逆エラーと比較します)。これはトレリス量子化と呼ばれます。x264の作者(Loren Merritt)によるH.264でのトレリス量子化の実装に関する注意を参照してください。彼は目的のかなり基本的な説明から始めます。
ピーターコーデス

とにかく、JPEGエンコーダーはエントロピーコーダーでうまく圧縮されるようにDCT係数を選択している可能性があります。そのため、最適なコンプレッサーでも回転バージョンを小さくすることはできません。(異なる順序で配置するとおそらく圧縮率が低下するためです。)8x8のブロックはすべて個別にコーディングされているため(エントロピーコーダーAFAIKの状態をリセットするため)、これはほとんど確実にJPEGの小さな効果になります。(h.264のIフレームはイントラ予測を使用し、同じフレームの他のブロックから予測し、同じ視覚品質のJPEGよりも小さくします。)
Peter Cordes

24

私は先に進み、何が起こっているのか理解できるかどうかを確かめるために実験を繰り返しました。

手順

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%大きくなります。

概要

  • WPVは「真の」ロスレス回転を行っていないかもしれませんが、回転は実質的にロスレスであるようです。

  • 余分なサイズは、追加されたメタデータの固定量によるものと、効率の低いエントロピーコーディングによるものです。

バージョン情報:

  • 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
    

20

編集:この回答は、ファイルのサイズが約9 KiB(256×256画像の場合は9055バイト、512×512画像の場合は9612 KiB)増加したことを知る前に投稿されました。

おそらく、最初に画像を回転させたときに、Windows Picture Viewerは次のいずれか(または両方)を実行しました。

  1. 元のJPEG画像にないEXIFタグ(おそらくOrientationタグ)を追加しました。
  2. 既に存在するタグに変更/追加された情報(おそらく、Processing SoftwareまたはImage Softwareタグ)。

追加のEXIFタグ(および/または既存のタグへの追加データ)により、ファイルサイズが増加しました。

WPVが追加または変更したすべてのタグおよび/またはタグデータが既に存在していたため、その後のローテーションでファイルサイズが増加することはありませんでした。オリエンテーションタグののみが変更されました(そして、おそらく日付/時刻タグの値も)。


編集:この説明では、ファイル内の約9 KiBの追加データを説明できないことはほぼ確実です。さらに、サイズが増加する他の理由がない限り、この説明では、サイズの増加がほぼ一定であると予想します(数値データの文字列表現間の長さの差、おそらく数バイト)。これは明らかにここで起こっていることではなく、少なくとも完全な説明ではありません。


1
また、EXIFタグは9kBを占有しますか?まあ、これは少なくともテストが簡単です-OPに回転した画像からEXIFまたは他のタグを削除させ、ファイルサイズがどのように変化するかを確認してください。
カール・ウィットフト

2
@CarlWitthoft 9kBは新しい情報です。それに言及するための編集。
-scottbb

3

jpeg en / decoderをリバースエンジニアリングしなければ、確実に言うことは不可能です。実際には多くのjpeg標準があり、一般的な考えに反して、すべてを再エンコードせずに変更できるわけではありません。

最初の保存、その好まれるjpegフレーバーへの不可逆的な書き換えであり、後続のローテーションは、単純なメタデータ調整またはDCTテーブルでの直接的な操作である可能性があります(エンコードスキームによっては可能です)。

ファイルサイズの増加には追加のメタデータも含まれる場合がありますが、9kは多くのように見えますが、可能です。この増加は、GIMPからの出力に存在しなかった可能性のあるサムネイルの追加によっても考慮される場合があります。ファイルから直接(WPVの前後に)より多くの情報を取得できる場合があります。

いずれにせよ、jpegで無損失で作業しようとすることは、特定の画像サイズでのみ有用であり、すべてのデコーダーとエンコーダーが同一ではなく、信頼できないjpegコンテンツを直接編集するエディターを必要とするため、本当にばか用ですケース...今そうしているからといって、それが今後も続くというわけではありません。

より良い方法は、ロスレス形式で作業し、痛みを完全に回避することです。


2
私は、jpegデータを回転させると、そもそも再エンコードが発生するはずだとはまったく確信していません。
カールウィットソフト

あなたがプログラマであるかどうかに依存します...私の推測では、あなたはそうではありません。最小限の変更を行うには、その最適化を具体的に探す必要があります。そうしないと、保存操作は非圧縮ビットマップから開始されます。
ジェームス・スネル

3
リンクされた質問から、Windows Photo ViewerがJPEGを可逆的に回転させることは明らかです。
vclaw

2
@James私は低レベルのプログラマーではありません。テレビでプレイします:-)。OPは、再エンコードが行われる場合と行われない場合の正確な説明へのリンクを提供しました。その議論から、彼は$ \ frac {\ pi} {2} $だけ回転していると推測していました。任意の角度の回転により再エンコードが発生することに同意します。そのため、X-Y-Y画像が少なくとも斜辺と同じ大きさの領域に埋め込まれていない限り、情報が失われます。
カールウィトフト

1
WPVは、8/16の倍数の次元の画像に対して可逆的に回転していることを知っています。OPにリンクされている質問に対するMatt Grumの回答に対する@Tristanのコメントを参照してください。トリスタンはマイクロソフトのWPVチームで働いており、基本的に確認しています。
scottbb

1

ロスレスJPEG回転は、画像のサイズがブロックサイズの倍数である場合(通常[/ always?] 8)にのみ、境界アーティファクトの導入なしで可能です。関係する内容の詳細については、jpegtranのマニュアルページを参照してください(申し訳ありませんが、適切な正規のリンクがありません。見つけた場合は自由に編集してください)。

転置変換には、画像の
寸法に関する制限はありません。他の変換は、画像の大きさがiMCUサイズの倍数(通常8または16ピクセル)でない場合、DCT係数データの完全なブロックのみを必要な方法で変換できるため、かなり奇妙に動作します。

奇数サイズの画像を変換するときのjpegtranのデフォルトの動作 は、変換セットの
正確な可逆性と数学的な
一貫性を維持するように設計されています。前述のように、転置は
画像領域全体を反転できます。水平ミラーリングでは、右端の一部のiMCU列はそのまま残りますが、画像のすべての行を反転できます。同様に、垂直ミラーリングでは、下端の一部のiMCU行はそのまま残りますが、すべての列を反転できます。他の変換は、転置および反転操作のシーケンスとして構築できます。一貫性を保つため、エッジピクセルに対するアクションは、対応する転置およびフリップシーケンスの最終結果と同じになるように定義されています。

実用的に は、変換後の画像

右端や下端に沿って奇妙な外観のストリップを作成するのではなく、変換不可能なエッジピクセルを破棄することをお勧めします。これを行うには、-trimスイッチを追加します。

Windowsフォトビューアーは、実際に可逆回転を実行するのではなく、圧縮解除と非常に高品質の再圧縮を実行して画像のサイズが8の倍数でない場合に可逆動作をシミュレートすることで、この問題を回避していると思われます。優れたユーティリティは、画像全体の品質を損なう(およびファイルサイズを増やす)のではなく、実際のロスレス、アーティファクト、およびすべてを実行するか、数ピクセルをドロップするだけです。


1
256x256画像には関係ありません。
16年

誤解し、問題は257x257バージョンのものだと思いました。
R ..

0

私には明確な答えはありませんが、それが起こった理由のいくつかの可能な理論があります。一部のファイルタイプは、そのファイルタイプのイメージの2つの異なるコードが必ずしも異なるイメージを生成するわけではありません。たとえば、PNGファイルタイプは透明な背景を許可しますが、背景が透明で、同じ背景が白であることを除いて同じ画像はまったく同じように表示されるため、そのように機能します。画像ファイルは、ピクセルあたり3バイト未満のメモリしか使用しない場合、圧縮されていると言われます。背景が透明なものを除き、2つのPNGファイルがまったく同じ画像を生成することはないと思います。画像をPNGとして保存すると、元の画像を生成するコードに変換され、各ピクセルが2 ^ 24色のランダムな色であるような非常に珍しい画像を除き、コードは1ピクセルあたり3バイトより少ないメモリを使用するため、PNGとしての保存はロスレス圧縮と呼ばれます。一方、メモリを節約するために、特定の画像のみをJPEG画像ファイルのコードによって生成できます。おそらく複数のJPEGファイルタイプがあり、それらのいずれかがそのファイルタイプの2つの異なる画像がまったく同じ画像を生成できるという特性を持っているかどうかは知りません。私はあなたがちょうど画像を回転させてJPEGとして保存した回数を仮定しており、それがあなたがしたことであると仮定して何が起こったのかを説明します。回転して保存する前とまったく同じ画像ファイルコードを取得する方法があれば、回転は無損失です。ロスレス回転を実際に行ったことが正しくない場合があります。本当にロスレスだったら、


-3

この背後にある理由はいくつかあります

画像のコード化と圧縮の方法は、単に圧縮アルゴリズムのためにサイズを変更します。ビットマップとして保存してから回転することで、これをテストできます。その形式または生の形式では、サイズは同じままである必要があります。そうでない場合、画像を保存するプログラムは新しいデータを追加している可能性があり、メタデータなどが追加されています。

しかし、なぜjpegを20回回転させるのですか?


2
少なくともWindows Picture Viewerの元の質問のリンクを読んだ場合、JPEGの次元が8の倍数である場合、WPV でのJPEGSの回転はロスレス変換です。これをテストする簡単な方法は、4回回転し(結果として元の方向と同じになる)、単純なピクセルごとの画像減算を実行することです。
scottbb

@scottbbこれは、必ずしもWindows画像ビューアの問題ではありません。非可逆形式を回転させるものはすべて、圧縮を再計算する必要があります。8の倍数で画像を回転すると、すべてが8ビットワードに収まり、アーティファクトを追加する方法で圧縮されない場合があります。これは、アルゴリズムの仕組みに基づいており、使用するプログラムに実装されています。
Cc Dd

-3

画像の圧縮方法のため。一般に、PNGやJPGなどの形式では、回転後にファイルサイズが保持されません。

圧縮器にとって、回転した画像は単なる圧縮画像です。compressioneのヒューリスティックの仕組みにより、回転した画像を同じように圧縮する保証はありません

もちろん、圧縮が無損失の場合、画像を4回回転させると、画像は再び同じになります(元の画像と同じになるまで回転します)。その場合は、同じ圧縮サイズになります。これは、次のいずれかの理由によるものです。

  • メタデータを追加しました:プログラムは何らかの理由でテキストのチャンクを追加しました
  • コンプレッサーの変更:プログラムは、変更がない場合は元の画像を再保存することを選択できますが、変更を適用すると(90度の4回転でも)、独自の画像を使用して画像を再圧縮することができますコンプレッサー(プログラムは、それが同じ画像であることを認識しなくなりました)。
  • 一般に、同じコンプレッサー(libPNGまたはlibJPG)は、異なる実装、同じライブラリの異なるバージョン、異なる圧縮パラメーターで非常に異なる結果をもたらします(また、動作システムとコンパイラーもここで違いを生じます)。

画像圧縮は、画像を4x4または他のサイズのチャンクに圧縮することにより機能します。一般的に、コンプレッサーは回転した画像を別の画像と見なしますが、圧縮されたピクセルチャンクは単なる線形分解であるため、画像上のチャンクが同じ場合、線形分解行列を効果的に同じに変換/ミラーリングすることが可能です品質:

これは機能ごとに実装する必要があり、最初の回転時のサイズの初期増加=>回転可能なチャンクで画像を圧縮しようとするだけであることに注意してください:

  • そうしないと、画質が低下します
  • 成功した場合は、サイズを1回だけ増やしてから、すべての回転で同じ品質を維持します。

  • その操作は、画像が等しいチャンクで作成されている場合にのみ成功します。(画像のサイズはチャンクのサイズの倍数です)。

scottbbの答えは間違っているため、簡単なテストを実行できます。

  • 元の画像を開く:スクリーンショット
  • WPVで画像を4回回転:スクリーンショット
  • 2つのスクリーンショットを比較する

画像が変更されます(最初の回転で再圧縮されます)。ただし、その変更には時間が限られているため、品質を損なうことなく再度回転できるようになりました(画像のサイズが8の倍数である場合)

OPに直接回答するには:

ロスレスで回転していることを知っています

ロスレスで回転しているのではなく、少なくとも一度は品質を失い(最初の回転:最初に回転可能な方法で圧縮する必要があるため)、その後品質を維持します。


1
問題はロスレス回転に関するものであるため、再圧縮は回避されます。
Agent_L

5
OPは一般的なケースではなく、特定のソフトウェアの1つとそれを行う特定のケースについて正確に尋ねました。あなたの答えは間違っていません。OPが尋ねたものとは異なる質問に答えているだけです。
Agent_L

1
最初の3つの文は、「画像の圧縮がどのように機能するか」という別の質問に対するものです-可逆回転では圧縮は行われません。「コンプレッサーに回転した画像」-再び、コンプレッサーは呼び出されません。「圧縮が可逆的である場合」-圧縮は不可逆的です。回転はロスレスです。さて、これは私がこの議論を喜んで受け入れているところです。私はあなたの意見を見ることができます、私はそれに同意します、しかしそれはここで完全に場違いです。ところで、私もプログラマーであり、生のファイルの読み取りと書き込みを共有しました。
Agent_L

1
ペイントでイメージを作成し、4回回転させて同じにしましたが、サイズは1.6 KBから8.1 KBにジャンプしました。バイナリdiffは、画像データが変更されていないことを示してい<?xpacketます。これは、タグ内のメタデータの巨大な塊です。
Agent_L

1
JPEGのサイズが8(またはサブサンプリングでは16)で割り切れる場合、90度単位でロスレスに回転できます。重要なのは、RGBに完全にデコードするのではなく、DCT係数を直接操作することです。これは特殊な機能で、一般的な画像エディターにはあまり含まれていません。たとえば、en.wikipedia.org/wiki/Libjpeg#jpegtranを参照してください。質問で指定されているようにWindowsフォトビューアーで実験を実行した場合、それは実際にロスレスであることがわかります。
マークランサム
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.