We often want to use resources rationally. So, we can compress images and save some memory. This article is about JPEG and PNG compression using ffmpeg. Do you know that by compressing black&white images in PNG format, you can save 30% of memory without loss of quality? So, if our image is about 352K we can receive about 262K after compression. In PNG format! Yes, PNG is lossless, but it have some algorithms which affect on compression speed. So, if we make the compression longer then PNG compression will save more memory!
Oh! If you want to read about WebP compression see this article(WebP for image encoding and decoding)
What PNG compression level means?
We affect only speed of compression! If it takes longer then it saves more memory! Without loss of quality since PNG format is lossless.
What JPEG compression means?
Since JPEG format is lossy (with loss of quality) the better compression makes less quality. If compression really high then image looks very bad. So It needs a balance of compression level.
Compress PNG images with ffmpeg
We can use -compression_level option. It is from 0 to 100.
100 means maximum compression but takes more time (but I didn’t see the difference because it’s still fast). We can compress all PNG images without loss of quality with the following command
ffmpeg -i input_image.png -compression_level 100 output_image.png
To make sure that the quality has not changed we can compare md5 hashes of uncompressed images (raw format)
ffmpeg -loglevel error -i input_image.png -f md5 - output: MD5=5a8880efee7fbc9cb89f2c2df776b565 ... ffmpeg -loglevel error -i output_image.png -f md5 - output: MD5=5a8880efee7fbc9cb89f2c2df776b565
So, these are two identical pictures with different compression levels.
Compress JPEG images with ffmpeg
The -compression_level option also works with JPEG images. I really didn’t see the difference between images, but it saved me about 50% of memory. I tried to uncompress it and compare md5 hashes but they looks different. So, there is a loss of quality.
ffmpeg -i input_image.jpg -compression_level 100 output_image.jpg
Another option -qscale is more aggressive. You can turn an image into a set of squares. It is from 0 to 100. The less value means better quality but less compression. The greater value means less quality but better compression. The :v specifier in -qscale option means “for video stream”.
ffmpeg -i input_image.jpg -qscale:v 3 output_image.jpg
The -q option means the same. It is just a more modern version of -qscale option.
ffmpeg -i input_image.jpg -q:v 3 output_image.jpg