PNGファイルは可逆圧縮を使用すると言われています。ただし、GIMPなどの画像エディターを使用して、画像をPNGファイルとして保存しようとすると、0〜9の範囲の圧縮パラメーターが要求されます。圧縮された画像、それはどのようにPNGをロスレスにしますか?
圧縮パラメーターを9に設定した場合にのみ、ロスレス動作を取得できますか?
PNGファイルは可逆圧縮を使用すると言われています。ただし、GIMPなどの画像エディターを使用して、画像をPNGファイルとして保存しようとすると、0〜9の範囲の圧縮パラメーターが要求されます。圧縮された画像、それはどのようにPNGをロスレスにしますか?
圧縮パラメーターを9に設定した場合にのみ、ロスレス動作を取得できますか?
回答:
PNGはロスレスです。この場合、GIMPは最良の単語を使用していない可能性が高いです。「圧縮の品質」、つまり「圧縮のレベル」と考えてください。圧縮率を低くすると、ファイルサイズは大きくなりますが、作成にかかる時間は短くなりますが、圧縮率を高くすると、ファイルサイズが小さくなり、作成に時間がかかります。通常、最高の圧縮レベルに達すると、減少するリターン(つまり、時間の増加と比較してサイズの減少は少なくなります)が得られますが、それはユーザー次第です。
pngcrush
は、可能な限り最小の多くのバリエーションを比較できるようなツールを使用してください。
圧縮レベルは、ファイルサイズとエンコード/デコード速度のトレードオフです。過度に一般化するために、FLACなどの非画像形式でも同様の概念があります。
ファイルサイズは異なりますが、圧縮レベルが異なるため、実際のデコード出力は同じになります。
MD5マルチプレクサを使用して、デコードされた出力のMD5ハッシュを比較できます。ffmpeg
これはいくつかの例で最もよく示されます:
$ 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
$ ffmpeg -loglevel error -i 0.png -f md5 -
3d3fbccf770a51f9d81725d4e0539f83
$ ffmpeg -loglevel error -i 100.png -f md5 -
3d3fbccf770a51f9d81725d4e0539f83
両方のハッシュが同じであるため、デコードされた出力(非圧縮の生のビデオ)がまったく同じであることが保証されます。
ffmpeg -ss 30 -i input -vframes 1 output.png
また、画像からビデオを作成したり、その逆を行う場合にも適しています。
PNG圧縮は2段階で行われます。
ステップ2は非常に時間とリソースを消費するタスクであるため、基礎となるzlibライブラリ(生のDEFLATEのカプセル化)は、1 =最速の圧縮、9 =最適な圧縮、0 =圧縮なしの範囲の圧縮パラメーターを使用します。それが0-9の範囲の由来であり、GIMPは単にそのパラメーターをzlibに渡します。レベル0では、PNGは実際には同等のビットマップよりもわずかに大きくなることに注意してください。
ただし、レベル9はzlibが試行する「最良の」だけであり、依然として非常に妥協したソリューションです。
これを実際に把握するために、徹底的な検索で1000倍以上の処理能力を費やしたい場合は、zlibの代わりにzopfliを使用すると、3-8%高いデータ密度を得ることができます。
圧縮は依然としてロスレスであり、データのより最適なDEFLATE表現にすぎません。これは、zlib互換ライブラリの制限に近づくため、PNGを使用して達成できる真の「最良の」圧縮です。
PNG形式の主な動機は、GIFに代わるものを作成することでした。これは、無料であるだけでなく、基本的にすべての点で改善されました。その結果、PNG圧縮は完全にロスレスです。つまり、元の画像データは、GIFやほとんどの形式のTIFFと同様に、ビットごとに正確に再構築できます。
PNGは2段階の圧縮プロセスを使用します。
事前圧縮ステップはフィルタリングと呼ばれます。これは、メイン圧縮エンジンがより効率的に動作できるように、画像データを可逆的に変換する方法です。
簡単な例として、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章-圧縮とフィルタリング
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を参照してください。
ロスレスなものの圧縮レベルは、常にエンコードリソース(通常は時間、場合によってはRAM)とビットレートを交換するだけです。品質は常に100%です。
もちろん、ロスレスコンプレッサーは実際の圧縮を保証することはできません。ランダムデータは非圧縮性であり、検索するパターンも類似性もありません。シャノン情報理論とそのすべて。ロスレスデータ圧縮のポイントは、通常、人間は非常に非ランダムなデータを扱うことですが、送信と保存のために、できる限り少ないビットに圧縮することができます。できれば、オリジナルのコルモゴロフの複雑さに可能な限り近づけてください。
zipまたは7zの汎用データ、png画像、flacオーディオ、またはh.264(ロスレスモード)ビデオのいずれであっても、同じことです。lzma(7zip)やbzip2などの一部の圧縮アルゴリズムでは、圧縮設定を上げると、デコーダーのCPU時間(bzip2)が増えるか、必要なRAMの量が増えるだけです(lzmaとbzip2、参照フレームが多いh.264) 。多くの場合、次のバイトのデコードは数メガバイト前にデコードされたバイトを参照するため、デコーダはより多くのデコードされた出力をRAMに保存する必要があります)。bzip2でも同じで、大きなブロックサイズを選択しますが、解凍速度も遅くなります。 lzmaには可変サイズの辞書があり、1を必要とするファイルを作成できます。
まず、PNGは常にロスレスです。明らかなパラドックスは、(あらゆる種類のデータに対して)2種類の圧縮が可能であるという事実によるものです:損失の多い圧縮と損失のない圧縮。
ロスレス圧縮は、さまざまなトリックを使用してデータ(つまり、ファイルサイズ)を圧縮し、すべてを維持し、近似を行いません。その結果、ロスレス圧縮では、実際に圧縮がまったくできない可能性があります。(技術的には、エントロピーの高いデータは、ロスレス方式では圧縮が非常に困難または不可能になる場合があります。) 損失のある圧縮は実際のデータに近似しますが、近似は不完全ですが、この「精度の低下」により、通常、より良い圧縮が可能になります。
ロスレス圧縮の簡単な例を次に示します。黒の値を1,000回保存する代わりに、1,000個の黒ピクセルで作られた画像がある場合、カウント(1000)と値(黒)を保存して1000ピクセルを圧縮できます "画像」を2つの数字に変換します。(これは、ランレングスエンコーディングと呼ばれるロスレス圧縮方式の大まかな形式です)。