Nearly Lossless Image Compression with WebP

Created: Jan 05, 2023
Last Modified: Jan 05, 2023

! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc.
optimization
! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc.
utilities

Compress web images without losing quality!!

1. Installation 🍺

Install the homebrew package for webp.

$ brew install webp

2. Usage 💻

here’s the synopsis found in the official documentation

cwebp [options] input_file -o output_file.webp

From the documentation: Using -q float as an option -

Specify the compression factor for RGB channels between 0 and 100. The default is 75.

In case of lossy compression (default), a small factor produces a smaller file with lower quality. Best quality is achieved by using a value of 100.

In case of lossless compression (specified by the -lossless option), a small factor enables faster compression speed, but produces a larger file. Maximum compression is achieved by using a value of 100.

With that, a decent default to get pretty high quality, well compressed webp image would be:

$ cwebp -q 80 image.png -o image.webp`

Let’s take a 12 megapixel (3024 × 4032) photo shot on an iPhone 13.

you can see below that we’re dealing with a pretty hefty JPG! 4.3 MB! Wouldn’t want to load that image.. on the web!

➜  webp ls -lh
total 8816
-rw-------@ 1 remyhunter  staff   4.3M Dec  6 16:47 original.JPG

So we can run a little magic…

➜  cwebp -q 60 original.JPG -o new.webp
Saving file 'new.webp'
File:      original.JPG
Dimension: 4032 x 3024
Output:    1818614 bytes Y-U-V-All-PSNR 38.83 47.75 47.84   40.32 dB
           (1.19 bpp)
block count:  intra4:      32324  (67.87%)
              intra16:     15304  (32.13%)
              skipped:       367  (0.77%)
bytes used:  header:            547  (0.0%)
             mode-partition: 189165  (10.4%)
 Residuals bytes  |segment 1|segment 2|segment 3|segment 4|  total
    macroblocks:  |      14%|      24%|      20%|      41%|   47628
      quantizer:  |      27 |      24 |      19 |      13 |
   filter level:  |       8 |       6 |       4 |       9 |

..But doesn’t give us a perfect result. we’re losing some information and color data…

Here’s the side-by-side. left: original, right: compressed.

Look at that color loss in the compressed version. We could do way better than this!

Improvements ✨

I discovered that in order to retain the color information, we must retain the metadata. This was a bit confusing becuase the color spaces were both listed as RGB, but maybe there’s something we couldn’t see..

Regardless, I ran the following:

$ cwebp -q 60 original.JPG -metadata all -o compressed_withmetadata.webp

here’s a side-by-side with with this new image

The compression here is from 4.2M -> 1.2M which is pretty significant savings at 13 megapixels

The Verdict ⚖️

pros:

This comparison is considerably more accurate than the previous example,

So this is the magical command that works really well.

$ cwebp -q 60 [original] -metadata all -o [new-image.webp]

cons:

Desktop editing software isn’t up to date with webp encoding and decoding, so you won’t be able to perform edits after converting your image.

  1. Always keep the original images somewhere safe!
  2. Edit before you compress
  3. (Editing includes adjusting size)

Thanks for reading! Enjoy the size savings!

read more:

How to make a dark mode (vanilla js)"