3

My experiment (see image collage below):

  1. I created an white 640x400 image in GIMP and exported as png. It weights 1409 bytes.
  2. Then I added a black coloured line and exported as png. It weights 1694 bytes.
  3. Then, I coloured that line red and exported as png. It weights 1754 bytes.
  4. Starting from the white image in 1., I added a red square and exported as png. It weights 1426 bytes.
  5. From 4., I duplicated the red square and put it somewhere else in the image. I was expecting the png to weight 1426 + (1426-1409) = 1443. Instead, it weights 1729 bytes.
  6. Finally, I moved that red square elsewhere, hoping the image to weight 1729 bytes, and instead, it weights 1741 bytes.

I am utterly puzzled. I was expecting pixels to weight the same. This is clearly not the case. Well, maybe colors have different byte structure (e.g. red uses more 1s and 0s than white), but at least a red pixel weights the same everywhere. Steps 4 and 5 confirm that is not the case either. And finally, step 6 indicates that position also matters! Insane!

Can you please shed light on what is going on?

enter image description here

6
  • 12
    Have you done research into the compression algorithm for PNG? That might answer your question.
    – Vincent
    Oct 26, 2020 at 17:10
  • 7
    Have you tried your experiment with saving as BMP? I think most other file types (like PNG) will have compression and other information stored in addition to the pixels.
    – Jory L
    Oct 26, 2020 at 17:12
  • 1
    They have the same weight usually when loaded in memory. But not when written to disk siince most image formats are compressed. As a way to compare this try zipping big text files and see what happens to the size.
    – joojaa
    Oct 27, 2020 at 7:06
  • 4
    The full size of all the images is 768000 bytes. What you are seeing is how small you can compress the 768000 bytes depending on content. Why image file formats use built-in compression? Because otherwise files would be big. Why not ask the user to compress images manually using something like zip? Two reasons: first you can use custom compression algorithm for images to get better compression than zip and second you cannot display a zip file as an image in a web browser
    – slebetman
    Oct 27, 2020 at 7:51
  • 3
    Because PNGs utilise data compression in order to keep the file size lower:a kind of lossless compression, but compression nonetheless. So, 1 pixel does not correspond to a certain number of bytes.
    – Billy Kerr
    Oct 27, 2020 at 11:09

4 Answers 4

11

Compression efficiency

A naive bitmap encoding stores all the pixel values directly. However, since there almost always is some redundancy in the image data, compression can be applied to reduce the file size. For example, intuitively, "640x400 white pixels" is a sufficient description to exactly encode all the pixel values that takes only 20 bytes instead of 640x480x3 bytes.

One aspect of lossless compression is that some inputs will be more compressible than others (and, due to pigeonhole principle, many hypothetical inputs will be encoded to a larger file size than before - it's just that we don't expect to use such inputs in practice). This effect of different image features on compressibility is what you are observing in your experiments.

1
  • 2
    Also by the pigeonhole principle, the inputs that produce larger files, won't produce files that are very much larger. Adding one byte to the file size produces a file with 256 times as many pigeonholes for inputs to land in.
    – Mark
    Oct 27, 2020 at 21:58
5
  • White.. (all) pixels R255G255B255
  • Black line... (x) pixels R255G255B255 and (x) pixels R0G0B0
  • Red line... (x) pixels R255G255B255 and (x) pixels R255G0B0
  • 1 Red Square .... (x) pixels R255G255B255 and (x*2) pixels R255G0B0
  • 2 Red Squares .... (x) pixels R255G255B255 and (2 * x^2) pixels R255G0B0

You can see that with each iteration there is more data to store. Not a large amount more, but more nonetheless.

In other words, a pixel does not have a "set byte size" - all pixels are not the same byte size. The byte size changes based upon the data necessary to render that pixel. A pixel containing all one value for RGBA will be smaller than a pixel containing varied data for each color and/or alpha value.

This all boils down to what are referred to as Chunks in the PNG format and how bit reduction can be utilized in the compression scheme (DEFLATE).

You can read more about the PNG format and about DEFLATE, the compression scheme utilized in the PNG format, at Wikipedia.

2
  • @DanIsFiddlingByFirelight possibly.. I'm a designer, not a mathematician :) updated.
    – Scott
    Oct 27, 2020 at 22:07
  • This has nothing to do with PNG chunks. More relevant are the PNG row filters which can effectively predict repetitive patterns.
    – Nayuki
    Oct 27, 2020 at 23:00
3

The memory space needed for a pixel is the same, no matter what's its color or transparency level. Programmers have found ways to save space by letting their program to analyze patterns and instead of storing every pixel separately a found repeating rule how a pattern is constructed is saved. It really pays off, the available savings can be tens of percents and even more if some error is allowed like in JPG compression. Make a search for image compression methods.

1

File Formats

How pixels are stored depends on the file format. Most formats support some kind of compression which means that the amount of bytes used will depend on the complexity of the content of the image and not just on the mere number of pixels.

In a truly uncompressed format, each pixel will take the same amount. Try a standard *.bmp format to see that all your images have the same size.

The effect of compression as used by most formats has been explained in the other answers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.