3

http://jpegclub.org/jpegtran/から最新の win32 jpegtran.exeをダウンロードしたところ、次のことがわかりました。

14500 x 10000 ピクセルの 24 BPP jpeg テスト イメージを用意しました。

  • ファイルシステムの圧縮サイズは約7.5 MBです。
  • メモリに解凍すると (一部の画像ビューアーを使用)、約450 MBに膨らみます。

ロスレス ローテーション中の jpegtran.exe コマンド ライン ツールのメモリ消費を監視する (180) プロセスが最大900 MBのメモリを消費していることがわかります。

このようなjpeg ロスレス変換では、画像ファイルをメモリにデコードする必要はなく、代わりに、エンコードされたファイル自体に対して数学的変換を実行するだけで、メモリのフットプリントを非常に低く保つことができると想定していました。

次のうちどれが正しいですか?

  • この特定のツールの実装におけるいくつかのバグ
  • 私が逃したいくつかの設定スイッチ
  • 私の最後にいくつかの誤解があります(つまり、jpegロスレス変換も画像をメモリにデコードする必要がありますか?)
  • 「画像をメモリにデコードする」よりもさらに多くのメモリを消費する「数学演算」

編集:

JasonD の回答によると、理由は後者のようです。だから私は私の質問を拡張します:

これらの操作を小さなチャンクで実行できる実装はありますか(高いメモリ使用量を避けるため)? それとも、常に全体的に行う必要があり、それを回避する方法はありませんか?

PS:
独自のコーデック/アルゴリズムを実装する予定はありません。代わりに、私の要件を満たす実装があるかどうかを尋ねています。または、少なくとも理論的には可能であれば。

4

1 に答える 1

5

問題のライブラリについてはわかりませんが、jpeg画像でロスレス回転を実行するには、少なくともDCT係数を解凍して回転させてから、再圧縮する必要があります。

完全に拡張されたDCT係数は、より多くの情報を持っているため、元の画像データと同じサイズまたはそれより大きくなります。

jpegの損失は、DCT係数の量子化によって引き起こされるため、無損失です。これらをデコード/再エンコード/再量子化しない限り、損失は発生しません。

ただし、メモリを大量に消費します。

jpeg圧縮は次のように非常に大まかに機能します。

  • 画像をYCbCr色空間に変換します。
  • オプションで、一部のチャネルをダウンサンプリングします(カラーエラーはルミナンスエラーよりも知覚されにくいため、クロマチャネルを2倍ダウンサンプリングするのが一般的です)。これは明らかに損失がありますが、非常に予測可能/安定してそうです。
  • 離散コサイン変換(DCT)によって画像の8x8ブロックを変換し、画像を周波数空間に移動します。DCT係数も8x8ブロックにあり、8ビットの画像データよりも多くのビットをストレージに使用します。
  • DCT係数を可変量で量子化します(これはほとんどのパッケージの品質設定です)。目的は、できるだけ多くの小さく、特にゼロの係数を生成することです。これは、jpeg圧縮の主な「不可逆」の側面です。
  • 2Dデータをジグザグに移動して、おおよそ周波数順になっている係数の1Dストリームに変換します。高周波はゼロになる可能性が高いため、多くのパケットは理想的には切り捨て可能なゼロのストリームで終了します。
  • ハフマン符号化を使用して(現在はかなり圧縮可能な)データを(損失なく)圧縮します。

したがって、「非可逆」変換では、可能な限りそれを実行することを避けたいと考えます。特にDCT量子化以外のことは避けたいと思いますが、データの拡張を回避することはできません。

于 2012-12-06T23:17:01.833 に答える