web-dev-qa-db-ja.com

PNGに圧縮パラメータがあるとすると、PNGはどのようにロスレスになりますか?

PNGファイルは可逆圧縮を使用すると言われています。ただし、 GIMP のようにイメージエディタを使用していて、PNGファイルとしてイメージを保存しようとすると、圧縮パラメータが要求されます。 0から9の範囲です。圧縮画像の視覚的な精度に影響を与える圧縮パラメータがある場合、PNGをどのようにロスレスにしますか。

Compressionパラメーターを9に設定した場合にのみ、ロスレスの動作が得られますか?

153
pkout

PNGは無損失です。この場合、GIMPは最良のWordを使用していない可能性があります。それを「圧縮品質」、つまり「圧縮レベル」と考えてください。圧縮率が低いと大きいファイルになりますが、作成にかかる時間が短くなります。圧縮率が高いと、小さいファイルになり、作成に時間がかかります。通常、最高の圧縮レベルに達すると、収益が減少します(つまり、所要時間の増加に比べてサイズがそれほど減少しません)が、それはあなた次第です。

181
jjlin

PNGは圧縮されていますが、無損失です

圧縮レベルは、ファイルサイズとエンコード/デコード速度の間のトレードオフです。過度に一般化するために、FLACのような非画像フォーマットでも同様の概念があります。

異なる圧縮レベル、同じデコード出力

ファイルサイズは異なりますが、圧縮レベルが異なるため、実際にデコードされた出力は同じになります。

MD5マルチプレクサ を使用して、デコードされた出力の MD5 ハッシュとffmpegを比較できます。 - ).

これはいくつかの例で最もよく示されています。

PNGファイルを作成します。

$ ffmpeg -i input -vframes 1 -compression_level 0 0.png
$ ffmpeg -i input -vframes 1 -compression_level 100 100.png
  • デフォルトでffmpegはPNG出力に-compression_level 100を使います。

ファイルサイズを比較します。

$ du -h *.png
  228K    0.png
  4.0K    100.png

PNGファイルをデコードしてMD5ハッシュを表示します。

$ ffmpeg -loglevel error -i 0.png -f md5 -
3d3fbccf770a51f9d81725d4e0539f83

$ ffmpeg -loglevel error -i 100.png -f md5 -
3d3fbccf770a51f9d81725d4e0539f83

どちらのハッシュも同じなので、デコードされた出力(非圧縮の生のビデオ)はまったく同じであることを保証できます。

213
llogan

PNG圧縮は2段階で行われます。

  1. 事前圧縮は、汎用の圧縮アルゴリズムによって圧縮可能になるように画像データを並べ替えます。
  2. 実際の圧縮はDEFLATEによって行われます。DEFLATEは、重複するバイトシーケンスを短いトークンに置き換えることによってそれらを検索し、削除します。

ステップ2は非常に時間とリソースを消費するタスクなので、基礎となるzlibライブラリー(生のDEFLATEのカプセル化)は、1 =最速の圧縮、9 =最高の圧縮、0 =圧縮なしの範囲の圧縮パラメーターを取ります。それが0-9の範囲の由来であり、GIMPは単にそのパラメータをzlibに渡します。レベル0では、pngは実際には同等のビットマップよりわずかに大きくなります。

しかし、レベル9はzlibが試みる「最高の」ものに過ぎず、依然として妥協の解決策です
これを実感するために、徹底的な検索に1000倍以上の処理能力を費やしたい場合は、 zopfliを使用して3〜8%高いデータ密度を得ることができます。 zlibではなく
圧縮はまだ無損失です。データのDEFLATE表現としては最適です。これはzlibと互換性のあるライブラリの限界に近づくので、PNGを使って達成することが可能な本当の「最高の」圧縮です。

24
Adria

PNGフォーマットの主な動機は、無料であるだけでなく、本質的にすべての点でそれを改良したGIFの代わりを作ることでした。その結果、PNG圧縮は完全に無損失になります。つまり、GIFやほとんどのTIFF形式とまったく同じように、元の画像データを少しずつ正確に再構築できます。

PNGは2段階の圧縮プロセスを使用します。

  1. 圧縮前:フィルタリング(予測)
  2. 圧縮:DEFLATE( ウィキペディア を参照)

予備圧縮ステップはフィルタリングと呼ばれ、これは主圧縮エンジンがより効率的に動作できるように画像データを可逆的に変換する方法である。

簡単な例として、1から255まで一様に増加する一連のバイトを考えます。

1, 2, 3, 4, 5, .... 255

シーケンスに繰り返しがないため、圧縮率は非常に低いか、まったくありません。しかし、シーケンスの簡単な変更、つまり最初のバイトをそのままにし、後続の各バイトをその前のバイトとの差で置き換えることで、シーケンスは非常に圧縮可能なセットに変換されます。

1, 1, 1, 1, 1, .... 1

上記の変換は、バイトが省略されていないので無損失であり、完全に可逆的です。このシリーズの圧縮サイズは大幅に縮小されますが、元のシリーズはまだ完全に再構成できます。

実際の画像データがそれほど完璧であることはめったにありませんが、グレースケール画像やトゥルーカラー画像では、フィルタ処理によって圧縮率が向上するため、一部のパレット画像でも役立ちます。 PNGは5種類のフィルタをサポートしており、エンコーダは画像内のピクセルの各行に異なるフィルタを使用することを選択できます。

image

アルゴリズムはバイトに対して機能するが、大きなピクセル(例えば24ビットRGBまたは64ビットRGBA)に対しては対応するバイトのみが比較され、これはピクセルカラーの赤成分が緑および青の画素成分とは別に扱われることを意味する。

各行に最適なフィルタを選択するには、エンコーダはすべての可能な組み合わせをテストする必要があります。 20行の画像でも95兆以上の組み合わせでテストする必要があるため、これは明らかに不可能です。「テスト」には、イメージ全体のフィルタリングと圧縮が含まれます。

圧縮レベルは通常、0(なし)から9(最高)までの数字として定義されます。これらは速度とサイズの間のトレードオフを指しており、行フィルタのいくつの組み合わせを試すべきかに関係しています。これらの圧縮レベルに関する標準はないため、すべてのイメージエディタは、イメージサイズを最適化するときにいくつのフィルタを試すかについて独自のアルゴリズムを持つことができます。

圧縮レベル0は、フィルタがまったく使用されないことを意味します。これは高速ですが無駄です。より高いレベルはより多くの組み合わせがimage-rowsで試されて、最も良いものだけが保持されることを意味します。

最も簡単な圧縮方法は、各フィルタを使用して各行を段階的にテスト圧縮し、最小の結果を保存して、次の行に対して繰り返すことです。これは、画像全体を5回フィルタリングおよび圧縮することになり、これは、何度も送信および復号されることになる画像にとって妥当なトレードオフであり得る。ツールの開発者の裁量では、圧縮値が低いほど効果がありません。

フィルターに加えて、圧縮レベルはzlib圧縮レベルにも影響する可能性があります。これは0(最大のDeflate)から9(最大のDeflate)までの数値です。指定された0〜9のレベルがPNGの主な最適化機能であるフィルタの使用にどのように影響するかは、依然としてツールの開発者に依存しています。

結論として、PNGにはファイルサイズを非常に大幅に減らすことができる圧縮パラメータがあります。これらはすべて、1ピクセルも失われることはありません。

出典:

ウィキペディアのPortable Network Graphics
libpngのドキュメント第9章 - 圧縮とフィルタリング

16
harrymc

さて、私はその恩恵に遅すぎますが、とにかく私の答えはここにあります。

PNGは常にロスレスです。 Zipプログラムで使用されているものと同様に、Deflate/Inflateアルゴリズムを使用します。

Deflateアルゴリズムは、繰り返される一連のバイトを検索し、それらをタグで置き換えます。圧縮レベル設定は、プログラムがバイトシーケンスの最適な組み合わせを見つけるためにどれだけの労力を費やすか、およびそのためにどれだけのメモリが予約されているかを指定します。それは時間とメモリ使用量対圧縮ファイルサイズの間の妥協です。ただし、最近のコンピュータは非常に高速で十分なメモリを備えているため、最高の圧縮設定以外の使用はほとんど必要ありません。

多くのPNG実装は圧縮のためにzlibライブラリを使用します。 Zlibには1〜9の9つの圧縮レベルがあります。 Gimpの内部はわかりませんが、圧縮レベルが0〜9(0 =圧縮なし)に設定されているので、この設定は単にzlibの圧縮レベルを選択するものと想定します。

収縮アルゴリズムは、汎用圧縮アルゴリズムです。画像の圧縮用には設計されていません。他のほとんどのロスレス画像ファイル形式とは異なり、PNG形式はそれに限定されません。 PNG圧縮は、2次元画像を圧縮しているという知識を利用します。これはいわゆるフィルタによって実現されます。

(ここでのフィルタは実際には少し誤解を招く用語です。実際には画像の内容を変更するのではなく、単に別の方法でコーディングしています。より正確な名前はデルタエンコーダです。)

PNG仕様は5つの異なるフィルタを指定します(0 =なしを含む)。フィルタは、絶対ピクセル値を前のピクセルとの差、左、上、対角、またはそれらの組み合わせに置き換えます。これにより、圧縮率が大幅に向上します。画像上の各スキャンラインは異なるフィルタを使用できます。エンコーダは、各ラインに最適なフィルタを選択することによって圧縮を最適化できます。

PNGファイルフォーマットの詳細については、 PNG仕様書 を参照してください。

事実上無限の組み合わせがあるので、それらすべてを試すことは不可能です。それ故、効果的な組み合わせを見出すために異なる種類の戦略が開発されてきた。ほとんどの画像編集者は、おそらくフィルタを1行ずつ最適化しようとさえせず、単に固定フィルタを使用します(おそらくPaeth)。

コマンドラインプログラムpngcrushは最良の結果を見つけるためにいくつかの方法を試みます。他のプログラムで作成されたPNGファイルのサイズをかなり減らすことができますが、より大きな画像ではかなり時間がかかるかもしれません。 Source Forge - pngcrush を参照してください。

5
Pauli L

ロスレスなものの圧縮レベルは、常にビットレートに対してエンコードリソース(通常は時間、場合によってはRAMも)を交換するだけです。品質は常に100%です。

もちろん、ロスレスコンプレッサは 決して実際の圧縮を保証することはできません 。ランダムデータは非圧縮です。見つけるべきパターンも類似性もありません。シャノン情報理論とそのすべてロスレスデータ圧縮の全体的なポイントは、人間は通常非常にランダムではないデータを扱うということですが、送信と保存のために、できるだけ少ないビット数に圧縮することができます。元の Kolmogorov複雑度 にできるだけ近づけるようにしてください。

Zipまたは7zの一般的なデータ、PNG画像、Flacオーディオ、またはh.264(ロスレスモード)ビデオのどちらであっても、それは同じことです。 lzma(7Zip)やbzip2のようないくつかの圧縮アルゴリズムでは、圧縮設定を上げるとDECODERのCPU時間(bzip2)、あるいはもっと必要なRAMの量(lzmaとbzip2、そしてh)が増えるでしょう。より多くの参照フレームを有する264)。次のバイトのデコードは、数メガバイト前にデコードされたバイトを参照する可能性があるため、多くの場合、デコーダはRAMにデコードされた出力を保存する必要があります。 12フレームを参照して)。 bzip2と同じこと、そして大きいブロックサイズを選択すること、しかしそれはまたよりゆっくり解凍します。 lzma には可変サイズの辞書があり、デコードするのに1.5GBのRAMが必要なファイルを作成できます。

3
Peter Cordes

まず、PNGは常にロスレスです。明らかなパラドックスは、(あらゆる種類のデータに対して)2つの異なる種類の圧縮が可能であるという事実によるものです。

可逆圧縮は、さまざまなテクニックを使用してデータ(つまりファイルサイズ)を圧縮します。その結果、可逆圧縮では実際にはまったく圧縮できない可能性があります。 (技術的には、エントロピーの高いデータは、可逆的な方法では圧縮するのが非常に困難または不可能な場合があります。)非可逆圧縮は実データに近似しますが、近似は不完全しかし、この精度の「捨てる」ことで、通常はより良い圧縮が可能になります。

これは、ロスレス圧縮の簡単な例です。黒の値を1,000回格納する代わりに、1,000個の黒ピクセルで構成される画像がある場合は、カウント(1000)と値(黒)を格納して1000ピクセルを圧縮できます。 2つの数字に」 (これは、ランレングス符号化と呼ばれる可逆圧縮方式の原型です)。

0
GregD