Frage

Suppose I have an image file that I know is going to end up being 1024 x 1024, and I want to make that file as big (diskspace-wise) as possible. Assuming a 72-dpi resolution PNG file, what would I fill this file with to make it as information-dense as possible? Are certain colors more expensive to store than others? Patterns? Alpha-levels? I'm thinking about a PNG file specifically, but interested to know about GIF and JPG files, too.

War es hilfreich?

Lösung

In general PNG employs "lossless" compression, which usually works by finding repeated RGB values and/or repeated tiles or scanlines in the file. You can read more here:

http://www.libpng.org/pub/png/book/chapter09.html

In general, to defeat pretty much any lossless compressor, all you would have to do is to fill the image with random RGB noise, in such a way that RGB values of the pixels come outwildly different per scanline and per neighbouring pixel - that is, produce as few as possible repeating sequences of pixel color values. Knowing that you will be working with a file that has 1048576 pixels in total, which is just over a million, and 24 bit PNG gives you 16777216 colors to choose from (24-bit color, 8 bit per channel) you could try to sample every 16th color adjusting it's value ever slightly up and down when you sample, and just write it into the image.

For more interesting info on the topic see Concept check: any lossless data compression can be "defeated', right?

For a simple example, let's generate a PNG of your dimensions and fill it with random noise:

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`

This gives me a 4.2 megabyte file on OSX. When I run pngcrush on it to put in some compression I get a file of the same size. If you want to make an existing image non-compressible you could try mixing in noise in the same fashion.

Andere Tipps

You want to make the image difficult to compress, which, in Information Theory means "maximum entropy", which, in our case means: "white noise". Which, in practical term means: give each pixel a (uniform and independent) random value for each pixel value (each R-G-B component) in the 0-255 range. If you can add a ALPHA channel, do the same. (And, of course, if you are storing a PNG file, you could use 16 bitdepth... but I guess that would be cheating).

The file will be about 1024x1024x3 bytes = 3MB (if RGB, x4 if using RGBA) and PNG won't be able to compress it.

The same goes for GIF or JPEG (but with GIF you are restricted to indexed images, so the size will be about 1MB).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top