1

Following this post, I successfully reduced the byte size of an image to the desired level, but the problem is that I succeeded to do that only for JPEG. When I try to perform this for, say, png, the function does not do what is expected:

def get_highest_acceptable_quality(image, filename, target):
    q_min, q_max = 1, 96
    # Highest acceptable quality found
    q_acc = -1
    while q_min <= q_max:
        m = math.floor((q_min + q_max) / 2)
        buffer = BytesIO()
        image.save(buffer, format="png", compress_level=m) 
        s = buffer.getbuffer().nbytes # the s value is always the same for all values of m

        ...

The strange thing here is that the value of s remains the same irrespective of what the value of m is. Which is not the case for JPEG (here the entire function works just fine). I am completely lost because I am not a pro in image processing stuff. Any help?

Edgar Navasardyan
  • 4,261
  • 8
  • 58
  • 121

1 Answers1

2

JPEG is lossy. That means it is permitted to change your image pixels in order to reduce your filesize, i.e. you trade absolute accuracy for a decrease in size and transmission time. It tries to take advantage of the way we see things in order to make the quality loss less noticeable. For the technically inquisitive, I am referring to "chroma subsampling" whereby the colour information is sub-sampled because the human eye is more sensitive to brightness variation than to colour variation, and to "quantisation" whereby high frequency changes are weighted less or discarded because the human eye is better at seeing changes over a broader area than making out thousands of changes in a small, dense, confused area - see Wikipedia article on JPEG.

PNG, on the other hand, is always lossless. It cannot discard information or change pixels to make filesize smaller. Ultimately that means, with certain image types, it cannot reduce filesizes as far as JPEG.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • So this procedure of size reducing is possible only for JPEG, right ? – Edgar Navasardyan Jun 03 '20 at 08:53
  • Can you please provide a shortlist of those formats for which this procedure of quality decrease is meaningful? – Edgar Navasardyan Jun 03 '20 at 08:56
  • 1
    It's an enormous mess of tradeoffs. If you want Web-compatibility, you're stuck with JPEG, PNG, GIF. GIF can only do 256 colours and no 16-bit. BMP is dated, poorly documented, Microsoft and no good for compression of photos. TIFF is comprehensive but tries to be all things to all men. PNG is normally great but no good for float data and not ideal for photos. JPEG is great for photos but rubbish for computer-generated (blocky) graphics. You could try HEIC which compresses well and is what Apple have moved to but you will lose a lot of Web-compatibility. – Mark Setchell Jun 03 '20 at 09:48
  • One thing I didn't explicitly mention in my answer... you could reduce the number of colours yourself in your PNG in an attempt to make it smaller. – Mark Setchell Jun 03 '20 at 11:10
  • @MarkSetchell How would WebP compare? – Aurèle Jun 03 '20 at 16:32
  • 1
    @Aurèle There's some interesting and relevant thoughts here... https://googlechrome.github.io/essential-image-optimization/ – Mark Setchell Jun 03 '20 at 16:46