Search code examples
goencodefilesizeimage-compression

How to know the current "quality" of an image in golang? I need to reduce the file size


I'm trying to reduce/compress the file size of an image in golang. When i use jpeg.Encode and pass the options as param with Quality 75, an image of 10mb turns into a 18mb image.... I don't understand why, which is the concept of quality in this library?.

Also I want to know how can i know before encoding which is the original Quality, i think if i know that i can set it with smaller value or maybe trying another way like resizing the image 10% less of height and width.

I expect to understand the criteria of the Quality atribute of options param in jpeg.Encode function. I want to acquire more knowledge of image files size and how to reduce it.


Solution

  • JPEG quality parameter is not a feature of the image, but a feature of JPEG encoding process. Since JPEG is a lossy encoding, meaning that the encoded image cannot be decoded into the exact original, you can specify to the encoder how faithfully it should try to replicate the original. Quality 100 should have almost no loss, lesser qualities will have the encoder not try so hard. Consequently, the larger the quality parameter, the larger the file size, as the encoder tries to preserve more information.]

    To intuitively understand why an encoded file could end up larger than the original, here's an example of "compression" in human speech (not JPEG, but from information theory standpoint, same principles apply):

    00000000000000000000000000000000000000000000000000 can be described as "fifty zeroes", a compression of 50:12 ratio (i.e. the source length was reduced by over four times).

    01101 is "a zero, two ones, a zero and a one", a failure of compression at 5:34 ratio, the encoded value being almost seven times the original.

    This photo (from Wikipedia page on JPEG) shows the effect of the quality parameter on the resulting image, from 0 on the left to 100 on the right:

    effect of the quality parameter

    The encoder can't know without trying to encode an image what the result will be; that depends largely on the image. JPEG is very good at encoding colour gradations, and very bad at sharp edges. Thus, it compresses photographs really well, but will be extremely bad at e.g. static noise.

    This means there is no "original quality before encoding", unless your image is already JPEG-encoded. If an image is already JPEG-encoded, and you try to re-encode it, you will typically see few to no gains for an increase in size (as the encoder tries to replicate not just the image, but also the artefacts from the previous encoding), just like if you try to zip an already zipped file. Transcoding an image that is already encoded in some other way may or may not result in decrease in file size, depending on both the image and the previously used encoding.