Glossary

Chroma subsampling

Chroma subsampling is a compression step that stores color information at lower resolution than brightness, because the eye notices lost detail in brightness more than in color. In 4:2:0, the default for JPEG in libjpeg-turbo, each 2 by 2 block of pixels shares one blue-difference and one red-difference sample, so the image needs half as many raw samples as 4:4:4.

How it works

The image is first converted from RGB to YCbCr: Y is luma (brightness), Cb and Cr are the blue and red color-difference channels. For JPEG, the JFIF 1.02 specification defines this with the CCIR 601 coefficients Y = 0.299 R + 0.587 G + 0.114 B, Cb = -0.1687 R - 0.3313 G + 0.5 B + 128 and Cr = 0.5 R - 0.4187 G - 0.0813 B + 128. The encoder keeps Y at full size and downsamples Cb and Cr.

The ratio names how far each chroma channel is reduced compared with luma. Counting a block 4 pixels wide and 2 rows tall (8 Y samples):

  • 4:4:4: no subsampling. 24 samples per 4 by 2 block (8 Y, 8 Cb, 8 Cr).
  • 4:2:2: chroma halved horizontally, full height. 16 samples, two thirds of the data.
  • 4:2:0: chroma halved in both directions. 12 samples, half the data. VP8, the codec behind lossy WebP, works exclusively with 4:2:0 (RFC 6386).
  • 4:1:1: chroma quartered horizontally, full height. 12 samples, but with a different shape.

JPEG files describe the same thing as sampling factors. The luma component carries 2x2 for 4:2:0, 2x1 for 4:2:2 and 1x1 for 4:4:4, and both chroma components carry 1x1. The libjpeg-turbo cjpeg tool uses 2x2 (4:2:0) by default, and -sample 1x1 turns subsampling off.

convert -size 32x64 xc:red -size 32x64 xc:blue +append -fill black -draw 'line 0,0 63,63' t.png
convert t.png -quality 90 -sampling-factor 1x1 full.jpg
convert t.png -quality 90 -sampling-factor 2x2 sub.jpg
identify -format '%[jpeg:sampling-factor]\n' full.jpg sub.jpg
convert full.jpg -crop 4x1+30+10 +repage txt:- | awk 'NR>1{print $1,$3}'
convert sub.jpg  -crop 4x1+30+10 +repage txt:- | awk 'NR>1{print $1,$3}'
wc -c < full.jpg; wc -c < sub.jpg

The test image is 64 by 64 pixels, red on the left half and blue on the right, with a black diagonal line. Output from ImageMagick 6.9.12 with libjpeg-turbo 2.1.5, showing four pixels across the red-blue edge and the two file sizes in bytes:

1x1,1x1,1x1
2x2,1x1,1x1
0,0: #FE0000
1,0: #FE0000
2,0: #0000FE
3,0: #0000FE
0,0: #FE0000
1,0: #CA0C4A
2,0: #3300B4
3,0: #0000FE
713
522

With full chroma, the edge stays sharp. With 4:2:0, the two pixels at the edge pick up a blend of red and blue.

What does 4:2:0 mean?

4:2:0 means the two chroma channels have half the width and half the height of the luma channel. The zero in the last position does not mean zero chroma. As RFC 6386 puts it for VP8, each chroma sample corresponds to a 2 by 2 block of luma pixels, so the second row of each pair adds no chroma samples of its own.

Does subsampling affect quality?

It can. Subsampling shows most at sharp edges between saturated colors, as the blended pixels above show. On the synthetic test image above, 4:2:0 at quality 90 produced 522 bytes against 713 bytes for 4:4:4, but the numbers depend on the image.

Common pitfalls

  • Soft or fringed colored text: screenshots and UI graphics saved as 4:2:0 JPEG smear color at edges. Use PNG, or encode with 4:4:4.
  • Assuming high quality means no subsampling: the sampling factor is its own setting. Some encoders switch subsampling off at high quality settings: ImageMagick 6.9.12 used 2x2 at quality 89 in a test, and other encoders choose differently. Set it explicitly.
  • Reading 4:2:0 as a Y:Cb:Cr ratio: the zero does not mean the Cr channel is dropped. Both Cb and Cr are kept, each at half width and half height.
  • Expecting half the file size: the 50 percent figure counts raw samples before compression. The saved JPEG in the test above shrank by 27 percent (713 to 522 bytes).

Related terms

  • sRGB — the RGB color space whose values are converted to YCbCr before chroma is downsampled
  • Hex color — the RGB notation whose channels become Y, Cb and Cr

See also

  • Tool: Image Resizer — resizes images in the browser with JPEG, PNG or WebP output