Skip to content
PixelFerry

Convert JPG to WebP on a Mac

WebP compresses noticeably better than JPEG at the same perceived quality, which makes it the standard choice for web delivery. Converting existing JPEGs is a second lossy pass, so quality choice matters more than usual.

Updated

What changes in the file

A second lossy generation
The JPEG is decoded to pixels, artefacts and all, then re-encoded with a different lossy codec. WebP now has to spend bits describing JPEG's block artefacts as if they were image detail, which is why converting at low quality compounds badly.
Compression efficiency
WebP's VP8-derived intra coding uses better prediction and a smarter transform than JPEG's. Google's own WebP study measured files 25–34% smaller than JPEG at the same SSIM across four image sets, an average per corpus, not a promise for any one photograph. That study's baseline was libjpeg 6b; PixelFerry writes JPEG with mozjpeg, which is a stronger encoder, so the gap against a JPEG it produced is narrower.
An alpha channel becomes available
WebP supports transparency, which JPEG does not. Nothing to carry over from a JPEG source, but it means one format can serve both photographs and cut-outs on a site.
Chroma handling
Lossy WebP subsamples chroma at 4:2:0, like most JPEGs. Strongly saturated red or blue edges (a red logo on white) can soften slightly. Lossless mode avoids it entirely.

The generational cost, stated honestly

Most pages about this conversion imply you get the size saving for free. You do not, and the reason is worth understanding.

Your JPEG has already been through a lossy encoder. Its artefacts, the faint blocking in flat areas and the ringing around edges, are now part of the picture as far as any other codec is concerned. When WebP encodes it, it spends bits faithfully reproducing those artefacts.

The practical consequences:

  • Convert at a reasonably high quality, the app’s default of 80 is the place to start, and the result is usually hard to tell apart from the source at normal viewing size, while still being meaningfully smaller. This is the normal case and it works well.
  • Push the quality low and the two generations compound. You get a file that is small and visibly worse than a single-pass encode at the same size would have been.
  • If you still have the RAW, TIFF or PSD source, converting from that instead skips the problem entirely.

Picking a quality

WebP’s quality number is not JPEG’s quality number. They are different encoders with different internal models and there is no fixed conversion between them, a rule like “WebP q equals JPEG q plus ten” is folklore, not a property of either format.

So the useful method is not a table, it is a loop: start at the app’s default of 80, convert a representative handful, look at them at the size they will actually be viewed, and read the per-row before/after figures. Move the number and repeat if you need to. That takes a minute and is worth more than any threshold someone else picked for a corpus that is not yours.

Two things are worth knowing before you start:

  • Raise it, not lower it, when the source is a JPEG you cannot re-export. You are compressing something already compressed.
  • Lossless mode is for screenshots, diagrams and flat graphics, not for photographs: lossless photographic WebP is typically much larger than the JPEG you started with, which Google’s own FAQ warns about explicitly.

Browser support is no longer the question

WebP is supported by every current major browser and has been for years. Safari picked it up in 14, which is the release everyone was waiting on.

The remaining gaps are outside browsers: some desktop software, some older email clients, a few CMS upload validators. That makes WebP a delivery format. Keep your originals in a widely-readable format, and treat the WebP set as generated output, which is exactly how a batch converter fits into the workflow.

Converting a directory

Point PixelFerry at your images folder. It walks subfolders, so a content/uploads/2024/… tree comes in as one queue.

Set WebP, pick a quality, and (usually the bigger win) set a maximum width. A great many sites serve 4000-pixel photographs into a 1200-pixel column. When the gap is that wide, capping the width is usually the larger of the two savings, and doing both in the same pass means you only decode each file once.

Each finished row shows the before and after size with the percentage saved, so you can see immediately whether the settings are doing what you hoped rather than comparing folder sizes afterwards.

When people do this

  • Cutting the weight of an image-heavy site or blog archive without re-exporting every asset from its source.
  • Meeting a Core Web Vitals or page-weight budget where the images are the dominant cost.
  • Producing a smaller delivery set for a mobile app or a bandwidth-constrained deployment.

What macOS already does

cwebp, via Homebrew.Google's `cwebp` encoder is the reference implementation and gives you every switch the format has. `cwebp -q 80 in.jpg -o out.webp` is the basic form, and a shell loop covers a directory. It does have to be installed, because macOS reads WebP but does not write it, and `sips --formats` on macOS 26 lists `org.webmproject.webp` with no Writable flag.

Where it stops being enough:You would rather not install a toolchain, want to see before-and-after sizes per file, or need to resize in the same pass. cwebp's resize flag exists, but composing it with a folder walk is a script you have to write and maintain.

Limitations worth knowing first

  • This is generation two of lossy compression. Where the original source is still available, converting from that avoids the second generation entirely.
  • Some older software and a few email clients still do not render WebP, so it is a web delivery format rather than an archive or handoff format.
  • WebP is capped at 16383 pixels in either dimension, which very large panoramas and scans can exceed.

PixelFerry requires macOS 14 (Sonoma) or later on Apple silicon and Intel. Conversion runs entirely on your Mac. No file, and no part of one, is uploaded anywhere.