tooldura
Image & Media

WebP to JPG: What a Second Lossy Pass Actually Costs

T
tooldura editorial
8 min readUpdated October 29, 2026Open tool →

Turning a WebP into a JPG feels like changing a container. It is a recompression: the WebP is decoded into plain pixels, with its compression artefacts now part of the picture, and the JPEG encoder then compresses those pixels by its own, different rules. How much that second pass costs depends on how differently the two formats see an image, which turns out to be quite a lot, and on one setting you control.

How JPEG Cuts Up a Picture

Baseline JPEG, standardised as ITU-T T.81 in 1992, does everything on a fixed grid. The image is converted from RGB into one brightness channel and two color channels, the color channels are usually halved in both directions, and every channel is cut into 8×8 blocks.

Each block goes through a discrete cosine transform, which re-describes its 64 pixels as 64 frequencies, from flat tone up to the finest checkerboard. Those coefficients are divided by a quantization table and rounded, which is where detail is actually thrown away, and the rounded values are packed with Huffman coding.

Two properties matter here. The blocks never move: they always start at pixel 0 and step by 8. And every block is coded on its own, with nothing smoothing the boundaries between them. At low quality, those boundaries are the visible blocks people associate with JPEG.

How Lossy WebP Does It Differently

Lossy WebP is the intra-frame coder of the VP8 video format, specified in RFC 6386 and wrapped in the container RFC 9649 defines. It also works on brightness plus half-resolution color, but almost everything after that differs.

The image is cut into 16×16 macroblocks, and each one is first predicted from the already-decoded pixels above and to its left, using one of several directional modes. Only the difference between the prediction and the real pixels is transformed, with a 4×4 transform rather than 8×8, and quantized. The bits are then packed with a boolean arithmetic coder, which squeezes more out of the same data than Huffman can.

After decoding, an in-loop deblocking filter smooths the edges between blocks. That is why heavily compressed WebP looks soft and smeared where heavily compressed JPEG looks blocky. Google's comparison study measured lossy WebP at 25 to 34 percent smaller than JPEG at the same structural similarity score, and most of that gap comes from prediction and the better entropy coder.

The Two Formats Side by Side

Baseline JPEGLossy WebP
SpecificationITU-T T.81 (1992)VP8 key frame, RFC 6386, in RFC 9649 container
Color samplingUsually 4:2:0, can be 4:4:4Always 4:2:0
Block structure8×8 blocks on a fixed grid16×16 macroblocks, 4×4 transforms
PredictionOnly the DC value from the previous blockDirectional prediction from neighbours
Entropy codingHuffmanBoolean arithmetic coding
Block edgesLeft as they areSmoothed by a deblocking filter
TransparencyNoneSeparate lossless alpha plane
Typical artefactVisible 8×8 blocks, ringing at edgesSmearing, loss of fine texture

Why the Second Pass Hurts More Than It Should

Re-saving a JPEG at the same settings is close to harmless, because its coefficients already sit on the quantization grid and round to the same values. Converting WebP to JPEG gets none of that protection. The WebP's artefacts are smears and slightly displaced edges inside 16×16 regions. To the JPEG encoder they are simply detail, sitting at arbitrary positions relative to its 8×8 grid, and it spends bits describing them or rounds them into new errors.

The practical result is that the JPG carries both sets of artefacts: WebP's smoothing of fine texture, and JPEG's ringing and blocking on top. At high JPEG quality the second set is small enough to disappear. At low quality the two compound, and a picture that looked fine as WebP looks noticeably worse as JPG at a setting that would have been fine from the original.

🎯

Convert from the original if you can

If the WebP was made from a JPG or a camera photo you still have, convert from that instead. One compression from the source always beats two in a row, and it is smaller too. Converting the WebP is the right move only when it is the best copy you have, which for an image saved from the web it usually is.

Convert WebP to JPG and check what it cost

Quality 90 by default, a background color for transparency, and a full-size comparison on every file.

Open WebP to JPG →

Choosing the Quality for the JPG

The JPEG quality number scales the quantization tables. Here is where it lands on an image that has already been through WebP.

1

90 and up: keep the picture

The JPEG tables are scaled to a fifth of the standard values or less, so the encoder rounds away very little. The WebP's artefacts come through, and little new is added on top. This is the setting for anything that will be printed, edited or looked at closely.

2

80: a sensible size

The usual web default. From a clean source, 80 is hard to tell from 90. From a WebP that was itself compressed hard, faint blocking can start to show in skies and skin, so look at those areas before relying on it.

3

Below 75: only for a size limit

Both formats' artefacts are visible now. If a form insists on a small file, reducing the image's dimensions first saves far more than lowering quality and looks better.

4

100: no benefit

Quality 100 sets every quantization divisor to 1. The file grows sharply and nothing the WebP lost comes back. 92 to 95 gets you everything 100 does at a fraction of the size.

What Happens to Transparency

Lossy WebP can carry an alpha channel, stored separately from the color and compressed losslessly. JPEG has nowhere to put it. Every pixel has to become fully opaque, which means compositing the image onto a background color before encoding.

The formula is the standard "over" operation: each output channel is alpha × color + (1 − alpha) × background. A fully transparent pixel becomes the background, an opaque one keeps its color, and an anti-aliased edge pixel at 40 percent becomes a blend. Choose a background that matches where the JPG will be shown. Skip the step, and a canvas encoder treats transparency as black, because a transparent canvas pixel is stored as zero in every channel.

Frequently Asked Questions

Found this guide useful? Pass it on.

Related Tools

Keep Reading