最終的に 1024 x 1024 になることがわかっている画像ファイルがあり、そのファイルを (ディスク容量に関して) できるだけ大きくしたいとします。72 dpi の解像度の PNG ファイルを想定すると、このファイルをできるだけ情報密度の高いものにするには、このファイルに何を入力すればよいでしょうか? 特定の色は他の色よりも保管に費用がかかりますか? パターン?アルファレベル?特に PNG ファイルについて考えていますが、GIF および JPG ファイルについても知りたいと思っています。
2 に答える
一般に、PNG は「ロスレス」圧縮を採用しています。これは通常、ファイル内で繰り返される RGB 値および/または繰り返されるタイルまたはスキャンラインを検出することによって機能します。ここでもっと読むことができます:
http://www.libpng.org/pub/png/book/chapter09.html
一般に、ほとんどのロスレス コンプレッサを無効にするには、ピクセルの RGB 値がスキャンラインごとおよび隣接するピクセルごとに大きく異なるように、画像をランダムな RGB ノイズで満たすだけで済みます。つまり、ピクセルの色値の繰り返しシーケンスをできるだけ少なくします。合計で 1048576 ピクセル (100 万を少し超える) のファイルで作業することを知っていれば、24 ビット PNG では 16777216 色 (24 ビット カラー、チャネルあたり 8 ビット) から選択できます。サンプリングを試みることができます。 16色ごとに値を調整して、サンプリング時にわずかに上下させ、それを画像に書き込むだけです。
このトピックに関する興味深い情報については、 コンセプト チェックを参照してください。ロスレス データ圧縮は「無効」になる可能性があります。
簡単な例として、寸法の PNG を生成し、ランダム ノイズで埋めてみましょう。
require 'rubygems'
require 'chunky_png'
dimension = 1024
png = ChunkyPNG::Image.new(dimension, dimension)
total_colors = 2 ** (8*(3+1)) # 3 + 1 because we have alpha too!
rng = Random.new
(0...dimension).each do | x |
(0...dimension).each do | y |
r = rng.rand(0..total_colors)
png[x, y] = r
end
end
png.save('/tmp/noise.png')
`open /tmp/noise.png`
これにより、OSX で 4.2 メガバイトのファイルが得られます。それを実行pngcrush
して圧縮すると、同じサイズのファイルが得られます。既存の画像を非圧縮にしたい場合は、同じ方法でノイズを混ぜてみてください。
画像を圧縮しにくくしたい場合、これは情報理論では「最大エントロピー」を意味し、この場合は「ホワイト ノイズ」を意味します。これは、実際には、0 ~ 255 の範囲の各ピクセル値 (各 RGB コンポーネント) に対して (均一で独立した) ランダム値を各ピクセルに与えることを意味します。ALPHA チャンネルを追加できる場合は、同じことを行います。(もちろん、PNG ファイルを保存している場合は、16 ビット深度を使用できますが、それは不正行為になると思います)。
ファイルは約 1024x1024x3 バイト = 3MB (RGB の場合、RGBA を使用する場合は x4) になり、PNG では圧縮できません。
同じことが GIF や JPEG にも当てはまります (ただし、GIF ではインデックス付きの画像に制限されるため、サイズは約 1MB になります)。