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


157

PNGファイルは可逆圧縮を使用すると言われています。ただし、GIMPなどの画像エディターを使用して、画像をPNGファイルとして保存しようとすると、0〜9の範囲の圧縮パラメーターが要求されます。圧縮された画像、それはどのようにPNGをロスレスにしますか?

圧縮パラメーターを9に設定した場合にのみ、ロスレス動作を取得できますか?


40
ほとんどのロスレス圧縮アルゴリズムには、「辞書サイズなどの」調整パラメータがあり、「出力サイズを最小化するためにどれだけの労力をかける必要がある」スライダーで一般化されます。これは、GZipを、BZIP2、LZMA、... ZIPに有効です
ダニエルB

20
質問は別の方法で述べることができます。圧縮によって品質が失われない場合、最小サイズを生成する圧縮を常に使用しないのはなぜですか?答えは、圧縮と解凍に必要なRAMとCPU時間が増えるためです。場合によっては、より高速な圧縮が必要で、圧縮率についてはあまり気にしないことがあります。
カスペルド14年

14
PNG圧縮は、ZIPpingファイルとほぼ同じです。多少圧縮することはできますが、解凍すると正確なファイルが返されます。これがロスレスになります。
ミケバブコック14年

13
ZipやRarなどのほとんどの圧縮ソフトウェアでは、「圧縮レベル」を入力して、より小さいファイル<->より短い時間を選択できます。これらのソフトウェアが圧縮中にデータを破棄するわけではありません。この設定(GIMP、pngcrushなど)は似ています。
サルマン14

2
@naxa:ロスレスpngが実際にどれほど優れているかについての警告はありません。常に100%ロスレスです。この記事では、一部の古いブラウザーがガンマ補正を処理するためにPNG実装にあったバグについてのみ警告しています。そして、色をCSSの色(ガンマ補正されていない)と一致させる必要がある場合のみ意味があります。
パウリL 14

回答:


184

PNGはロスレスです。この場合、GIMPは最良の単語を使用していない可能性が高いです。「圧縮の品質」、つまり「圧縮のレベル」と考えてください。圧縮率を低くすると、ファイルサイズは大きくなりますが、作成にかかる時間は短くなりますが、圧縮率を高くすると、ファイルサイズが小さくなり、作成に時間がかかります。通常、最高の圧縮レベルに達すると、減少するリターン(つまり、時間の増加と比較してサイズの減少は少なくなります)が得られますが、それはユーザー次第です。


42
また、PNG圧縮には実際に多くの調整可能なパラメーターがあり、どちらの方向の調整でもソースの内容に応じて出力サイズを縮小できます。単純な「より良い」および「より悪い」スライダーよりもはるかに複雑です。一般的な目的のために、それはあまり重要ではありませんが、絶対的な最小値が必要な場合pngcrushは、可能な限り最小の多くのバリエーションを比較できるようなツールを使用してください。
ボブ14年

4
圧縮レベルを高くすると圧縮時間が長くなりますが、解凍にも影響しますか?
ノロナー14年

10
@Nolonar通常はありません。圧縮レベルを高くすると、通常、読み取りと処理に必要なデータが少なくなるため、解凍時間が短縮されます。圧縮時間が長くなるのは、圧縮するパターンを見つけるためのより徹底的な作業(単純化)が原因です。
ふわふわ14年

1
@fluffy LordNeckbeardの答えでは、最高の圧縮は最低の圧縮よりも5倍長い時間がかかりました。
アンドレチャレラ14

1
PNGの場合、圧縮率の高いファイルの解凍時間が長くなることよくあります。問題は、PNGの場合、ファイルが小さくなる限り圧縮アルゴリズムを繰り返し適用することです。サイズが大きくなると、適用を停止します。そのため、圧縮アルゴリズムを5回または6回適用することはかなり可能です。つまり、画像を表示するには5回または6回ファイルを解凍する必要があります。
yo

213

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-compression_level 100、PNG出力に使用します。

ファイルサイズの比較:

$ 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

両方のハッシュが同じであるため、デコードされた出力(非圧縮の生のビデオ)がまったく同じであることが保証されます。


26
+1は、ffmpegがpngを処理できることを知りませんでした。
Lekensteyn

21
@Lekensteyn スクリーンショットの作成に最適です。30秒スキップしてスクリーンショットを撮る例:ffmpeg -ss 30 -i input -vframes 1 output.pngまた、画像からビデオ作成したり、その逆を行う場合にも適してます。
llogan 14年

PNGをレンダリングするたびに解凍する必要があるということですか?それが本当なら、私たちは
akshay2000 14年

ディスクまたはキャッシュからファイルを再読み込みする場合は、はい、解凍する必要があります。同じページ内では、キャッシュはおそらく解凍されたバージョンを再利用できます。
デビッドマーテンソン14年

1
@ akshay2000 PNGをレンダリングするプログラムの動作に依存します。通常、ファイルはディスクから読み取られ、解凍されてRAMにバッファリングされます。したがって、RAMにバッファリングされている限り、イメージを再度解凍する必要はありません。
xZise

24

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

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

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

ただし、レベル9はzlibが試行する「最良の」だけであり、依然として非常に妥協したソリューションです。
これを実際に把握するために、徹底的な検索で1000倍以上の処理能力を費やしたい場合は、zlibの代わりにzopfliを使用すると、3-8%高いデータ密度を得ることができます。
圧縮は依然としてロスレスであり、データのより最適なDEFLATE表現にすぎません。これは、zlib互換ライブラリの制限に近づくため、PNGを使用して達成できる真の「最良の」圧縮です。


2
注:圧縮時間、またはzopflipngを使用する場合の反復カウントに関係なく、解凍時間は同じです。
アドリア14年

16

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種類のフィルターをサポートしており、エンコーダーは画像内のピクセルの行ごとに異なるフィルターを使用することを選択できます。

画像

アルゴリズムはバイトで動作しますが、大きなピクセル(24ビットRGBまたは64ビットRGBAなど)では、対応するバイトのみが比較されます。つまり、ピクセル色の赤成分は緑および青のピクセル成分とは別に処理されます。

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

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

圧縮レベル0は、フィルターがまったく使用されないことを意味し、高速ですが無駄があります。レベルが高いほど、より多くの組み合わせがイメージ行で試行され、最良の組み合わせのみが保持されることを意味します。

最適な圧縮の最も簡単な方法は、各フィルターで各行を段階的にテスト圧縮し、最小の結果を保存して、次の行で繰り返すことだと思います。これは、画像全体を5回フィルタリングおよび圧縮することになります。これは、何度も送信およびデコードされる画像の妥当なトレードオフになる可能性があります。ツールの開発者の裁量で、圧縮値を低くすると、パフォーマンスが低下します。

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

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

ソース:

Wikipedia Portable Network Graphics
libpng documentation第9章-圧縮とフィルタリング


1
圧縮レベルの設定がフィルターの使用を変更するとは思わない。レベル1〜9の設定は、おそらくzlib圧縮レベル1〜9を選択するだけで、レベル0はdeflateアルゴリズムがまったく使用されないことを意味します。ほとんどの実装では、おそらく行ごとにフィルターを変更せず、常にパスフィルターのみを使用します。
パウリL 14年

@PauliL:PNG圧縮ソフトウェアのすべての比較において、生成された画像のサイズには非常に大きな違いがあるため、同意しません。すべての製品が同じライブラリに対して同じパラメーターを使用している場合、すべてのサイズと速度が同じであるはずです。
ハリーマック

そのような比較へのリンクはありますか?
パウリL 14年

@PauliL:簡単な検索でこの比較ができました
ハリーマック14年

@PauliL:zlib圧縮レベルがPNGの圧縮レベルの影響を受けるのはおそらく正しいでしょう。圧縮ツールが正確に何をするかを文書化することはありませんが、それに応じて答えを修正しました。おそらく、最悪のサイズの結果を持つツールの説明は、フィルターをまったく使用せず、zlib圧縮のみを使用することです。
harrymc

5

OK、賞金には遅すぎますが、とにかくここに私の答えがあります。

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

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

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

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

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

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

PNGファイル形式の詳細については、PNG仕様を参照してください。

組み合わせの数は事実上無限であるため、それらすべてを試すことはできません。したがって、効果的な組み合わせを見つけるためのさまざまな種類の戦略が開発されています。ほとんどの画像編集者は、おそらくフィルターを行ごとに最適化しようとはせず、代わりに固定フィルター(ほとんどの場合Paeth)を使用しました。

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


3

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

もちろん、ロスレスコンプレッサーは実際の圧縮を保証することはできません。ランダムデータは非圧縮性であり、検索するパターンも類似性もありません。シャノン情報理論とそのすべて。ロスレスデータ圧縮のポイントは、通常、人間は非常に非ランダムなデータを扱うことですが、送信と保存のために、できる限り少ないビットに圧縮することができます。できれば、オリジナルのコルモゴロフの複雑さに可能な限り近づけてください。

zipまたは7zの汎用データ、png画像、flacオーディオ、またはh.264(ロスレスモード)ビデオのいずれであっても、同じことです。lzma(7zip)やbzip2などの一部の圧縮アルゴリズムでは、圧縮設定を上げると、デコーダーのCPU時間(bzip2)が増えるか、必要なRAMの量が増えるだけです(lzmaとbzip2、参照フレームが多いh.264) 。多くの場合、次のバイトのデコードは数メガバイト前にデコードされたバイトを参照するため、デコーダはより多くのデコードされた出力をRAMに保存する必要があります)。bzip2でも同じで、大きなブロックサイズを選択しますが、解凍速度も遅くなります。 lzmaには可変サイズの辞書があり、1を必要とするファイルを作成できます。


うーん、ドライブステッピングモーターとヘッドの制御を直接ヤンクして、ロスレス圧縮を保証する実装を見ました。高解像度のクロックソースがある場合、マンチェスターエンコーディングは簡単に破られます。
ジョシュア14

@Joshua ...高密度物理的記憶フォーマットは、データ圧縮と同じではありません使用
SAMB

0

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

ロスレス圧縮は、さまざまなトリックを使用してデータ(つまり、ファイルサイズ)を圧縮し、すべてを維持し、近似を行いません。その結果、ロスレス圧縮では、実際に圧縮がまったくできない可能性があります。(技術的には、エントロピーの高いデータは、ロスレス方式では圧縮が非常に困難または不可能になる場合があります。) 損失のある圧縮は実際のデータに近似しますが、近似は不完全ですが、この「精度の低下」により、通常、より良い圧縮が可能になります。

ロスレス圧縮の簡単な例を次に示します。黒の値を1,000回保存する代わりに、1,000個の黒ピクセルで作られた画像がある場合、カウント(1000)と値(黒)を保存して1000ピクセルを圧縮できます "画像」を2つの数字に変換します。(これは、ランレングスエンコーディングと呼ばれるロスレス圧縮方式の大まかな形式です)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.