Skip to content

WebP

currentMigrated from docs/images/WebP.mdx at 37c3317fd058; modified for Encode Wiki · CC BY-SA 4.0

WebP is Google’s image format from 2010: a lossy mode derived from the VP8 video codec, a separate lossless mode (VP8L) added in 2011, and an extended container with alpha, animation, ICC profiles and Exif/XMP metadata. It is standardised as RFC 9649 (informational, 2024) and implemented by Google’s libwebp, which provides cwebp, dwebp, img2webp, gif2webp and webpmux.

Its appeal today is compatibility: every current browser, OS image framework and image library decodes it, and it encodes quickly. Newer formats (AVIF, JPEG XL) compress better, but WebP is a safe default for web delivery, for transparent images and for replacing GIF.

Strengths

  • Lossy files noticeably smaller than JPEG at similar visual quality in most cases, with alpha available in lossy files too.
  • A lossless mode that is clearly smaller than PNG: on Google’s web-image corpus about 40 % smaller than plain libpng output and about 20 % smaller than ZopfliPNG-optimised PNG.
  • Animation with 24-bit colour and alpha, and per-frame lossy or lossless coding. Animated WebP is usually considerably smaller than GIF.
  • Universal support, fast encoding and decoding, royalty-free.

Weaknesses

  • Lossy WebP is 8-bit 4:2:0 only. There is no 4:4:4 or 10-bit lossy mode and no HDR, so saturated red/blue edges and coloured text bleed, and gradients can band.
  • Maximum 16,383 × 16,383 pixels in each direction.
  • The lossy format is based on VP8 and tends to smooth fine texture; it is clearly less efficient than AVIF or JPEG XL.
  • No JPEG-style progressive decode.
  • Lossless is 8-bit RGBA only; for 16-bit images use PNG or JPEG XL.
BrowserWebP
Chrome17+ (lossless and alpha from 23, animation from 32)
Edge18+
Firefox65+
Safari / iOS Safari14+

(From MDN’s WebP data.) That covers every browser still in use. Older software and some editors and apps are the remaining gaps. See image and audio support.

cwebp reads PNG, JPEG, TIFF, WebP and PNM.

Terminal window
cwebp -q 80 -m 6 input.png -o output.webp

-q is 0–100 (default 75); the scale is not JPEG’s, so compare by eye. -m 6 is the slowest, best compression method (default 4) and is worth it unless you are encoding enormous batches. Add -mt to use several threads.

GoalCommandNotes
Photocwebp -q 80 -m 6 in.png -o out.webp-preset photo, picture, drawing, icon and text tune the encoder for the content type; the preset must come first.
Sharper colour edgesadd -sharp_yuvSlower, more careful RGB→YUV 4:2:0 conversion; helps red text and thin coloured lines.
Losslesscwebp -lossless -z 9 in.png -o out.webp-z 0–9 is the lossless effort preset (-z implies -lossless); 9 is slowest and smallest.
Lossless with a little losscwebp -near_lossless 60 -z 9 in.png -o out.webp-near_lossless 0..100: 100 is off; lower is lossier. Still the lossless codec, so graphics compress better with no visible change.
Smaller alphacwebp -q 80 -alpha_q 80 in.png -o out.webpAlpha is coded separately and is lossless by default (-alpha_q 100); lower it to shrink soft masks.
Keep hidden RGB under transparencyadd -exactBy default cwebp is free to change colours of fully transparent pixels to compress better.
Hit a sizecwebp -size 50000 in.png -o out.webpSearches quality for a target byte size. -psnr 42 targets a PSNR instead.
Resize while encodingcwebp -resize 1280 0 -q 80 in.png -o out.webp0 keeps the aspect ratio.

With -lossless, -q no longer sets quality; it behaves as effort. Use -z instead.

cwebp writes no metadata by default, including ICC profiles. Wide-gamut images will look desaturated if you drop their profile, so pass -metadata icc (or -metadata all for Exif, XMP and ICC) when the source has one. cwebp does not apply Exif orientation to the pixels, so a rotated phone photo converted with the default -metadata none comes out sideways; rotate it first or keep the Exif.

Terminal window
gif2webp -lossy -q 70 -m 6 input.gif -o output.webp
img2webp -loop 0 -lossy -q 70 -d 100 frame1.png frame2.png frame3.png -o animation.webp

gif2webp is lossless unless you add -lossy or -mixed (per-frame choice); -min_size searches for the smallest result. img2webp takes explicit frame lists with a per-frame -d duration in milliseconds and per-frame -lossy/-lossless/-q. For video clips, AVIF animations or a real video format are much smaller. webpmux edits and inspects frames and chunks. dwebp only decodes still images; use anim_dump or a viewer for animations.

  • Lossless is for graphics, screenshots and masters. A lossless WebP of a photograph is several times the size of a lossy one.
  • -q 100 is lossy, not lossless; use -lossless.
  • The 16,383-pixel limit applies in both modes; downscale or split larger images first.
  • WebP files fed from lossy JPEGs compound loss; encode from the original where possible.
  • libwebp’s lossless decoder had a heap overflow, CVE-2023-4863, that was exploited in the wild in 2023. If you embed libwebp to decode untrusted uploads, keep it current.
  • AVIF and JPEG XL compress better and support more bit depths.
  • JPEG and PNG are the formats WebP most often replaces.
  • VP8 is the video codec behind lossy WebP.

The tables below are the full parameter references for cwebp, img2webp and gif2webp in libwebp 1.6.0. Reading option tables explains the Default column.

Complete cwebp 1.6.0 options and defaults
Parameter and aliasesType / accepted valuesDefaultMeaning and limits
-presetenumdefaultStart from a tuned set (default, photo, picture, drawing, icon, text); resets other options, so put it first.
-qfloat 0–10075Lossy quality 0–100, or lossless effort with -lossless. Disables -z.
-minteger 0–64Speed/size trade-off, 0 fast to 6 slowest and smallest. Disables -z.
-zinteger 0–9not enabledLossless preset 0 (fast) to 9 (slowest); implies -lossless and is ignored if -q or -m is given.
-losslessswitchoffEncode with lossless VP8L instead of lossy VP8.
-near_losslessinteger 0–100100 (no preprocessing)Lossless with pixel preprocessing: 100 is off, lower values discard more detail for smaller files.
-hintenumdefaultContent hint for lossless coding: photo, picture or graph.
-alpha_qinteger 0–100100Alpha-plane quality 0–100; below 100 makes alpha lossy, independent of -q.
-alpha_methodinteger 0–11Alpha compression: 0 stores it raw, 1 uses lossless coding.
-alpha_filterenumfastAlpha-plane prediction filter: none, fast or best.
-exactswitchoffKeep RGB values under fully transparent pixels instead of zeroing them.
-alpha_cleanupswitchoff (-exact is off)Hidden obsolete flag that turns -exact off; has no other effect.
-noalphaswitchoffDiscard the alpha channel.
-blend_alphahex RGBnot enabledComposite onto a hex RGB background (e.g. 0xffffff) and drop transparency.
-segmentsinteger 1–44Number of VP8 segments, 1–4; fewer is faster but less adaptive.
-snsinteger 0–10050Spatial noise shaping 0–100; higher spends bits on perceptually important areas.
-finteger 0–10060Loop-filter strength 0–100; 0 turns filtering off.
-sharpnessinteger 0–70Loop-filter sharpness 0 (most smoothing) to 7 (least).
-strongswitchonUse the strong loop filter, which also filters chroma.
-nostrongswitchoffUse the simple loop filter, which is faster.
-sharp_yuvswitchoffSlower RGB-to-YUV conversion that preserves sharp color edges better.
-partition_limitinteger 0–1000Allow quality loss 0–100 so the first partition fits its 512 KiB limit.
-sizenonnegative integer bytes0 (no target)Target output size in bytes (lossy only); approximate. Raises -pass from 1 to 6.
-psnrnonnegative float dB0 (no target)Target PSNR in dB (around 42 is typical); overrides -size. Lossy only.
-passinteger 1–101; becomes 6 for a size/PSNR targetAnalysis passes 1–10 for size or PSNR targeting; more is slower and closer to target.
-qrangetwo integers0 100Limit the quality search to MIN MAX within 0–100.
-afswitchoffExperimental: adjust filter strength automatically.
-jpeg_likeswitchoffExperimental: remap parameters so output size roughly matches JPEG’s, with less degradation.
-preinteger bitfield 0–70Experimental preprocessing bits: 1 segment smoothing, 2 dithering, 4 sharp YUV conversion.
-mtswitchoffUse multithreading where available.
-low_memoryswitchoffUse less memory at the cost of speed.
-stwo positive integersnot specifiedDeclare raw YUV420 input of WIDTH HEIGHT; not a resize.
-cropfour integers x y width heightnot enabledCrop to X Y WIDTH HEIGHT before any resize.
-resizetwo nonnegative integersnot enabledResize to WIDTH HEIGHT after cropping; a zero dimension keeps the aspect ratio.
-resize_modeenumalwaysWhen -resize applies: always, up_only or down_only.
-metadatacomma-separated tokensnoneCopy metadata from the input: all, none, exif, icc, xmp (comma-separated).
-opathnone (encode without saving)Output file; - writes to stdout.
-dPGM pathnot enabledWrite the decoded result of the lossy encode to a PGM file for inspection.
-mapintegernot enabledPrint a diagnostic map of encoder statistics; debugging only.
-print_psnrswitchoffPrint PSNR of the encoded result against the source.
-print_ssimswitchoffPrint SSIM of the encoded result against the source.
-print_lsimswitchoffPrint local-similarity score of the encoded result.
-shortswitchoffPrint a condensed statistics summary.
-quietswitchoffPrint nothing.
-vswitchoffPrint timing and extra diagnostics.
-progressswitchoffPrint encoding progress as a percentage.
-noasmswitchoffDisable assembly optimizations (SSE, NEON); for debugging.
-h, -helpactionnot requestedPrint the short help.
-H, -longhelpactionnot requestedPrint the full help.
-versionactionnot requestedPrint the library and libsharpyuv versions, then exit.
--actionnot requestedTreat the next argument as the input file and stop parsing options.
Complete img2webp 1.6.0 options and defaults
Parameter and aliasesType / accepted valuesDefaultMeaning and limits
-opathnone (encode without saving)Output animation file; - writes to stdout.
-loopnonnegative integer0 (infinite)Animation loop count; 0 loops forever.
-min_sizeswitchoffSpend more time to minimize size; disables inserted keyframes.
-kmininteger2147483646Minimum frames between keyframes; the default effectively disables inserted keyframes.
-kmaxinteger2147483647Maximum frames between keyframes; 1 makes every frame a keyframe, 0 or less disables inserted ones.
-mixedswitchoffPick lossy or lossless per frame automatically; per-frame -lossy and -lossless are then ignored.
-near_losslessinteger 0–100100 (no preprocessing)Near-lossless preprocessing 0–100 for lossless frames; 100 is off.
-sharp_yuvswitchoffSlower RGB-to-YUV conversion with better edges, for lossy frames.
-vswitchoffPrint frame order and timestamps.
-h, -helpactionnot requestedPrint help.
-versionactionnot requestedPrint encoder, mux and libsharpyuv versions, then exit.
-dpositive integer milliseconds100Display time in milliseconds for this and following frames.
-losslessswitchonEncode following frames losslessly (the default).
-lossyswitchoffEncode following frames lossily.
-qfloat 0–10075Quality 0–100 for following frames; lossless effort when lossless.
-minteger 0–64Speed/size trade-off 0–6 for following frames; 6 is slowest and smallest.
-exactswitchoffKeep RGB under transparent pixels in following frames; compositing can still discard it.
-noexactswitchonAllow following frames to zero RGB under transparent pixels (the default).
Complete gif2webp 1.6.0 options and defaults
Parameter and aliasesType / accepted valuesDefaultMeaning and limits
-opathnone (encode without saving)Output WebP file; - writes to stdout.
-lossyswitchoffEncode lossy instead of the default lossless.
-mixedswitchoffPick lossy or lossless per frame automatically.
-near_losslessinteger 0–100100 (no preprocessing)Near-lossless preprocessing 0–100 for lossless frames; 100 is off.
-sharp_yuvswitchoffSlower RGB-to-YUV conversion with better edges, for lossy frames.
-qfloat 0–10075Lossy quality 0–100, or lossless effort.
-minteger 0–64Speed/size trade-off 0–6; 6 is slowest and smallest.
-min_sizeswitchoffSpend more time to minimize size; disables inserted keyframes.
-kmininteger9 lossless; 3 lossy/mixedMinimum frames between keyframes; libwebp may adjust inconsistent kmin/kmax pairs.
-kmaxinteger17 lossless; 5 lossy/mixedMaximum frames between keyframes; 1 makes every frame a keyframe, 0 or less disables inserted ones.
-finteger 0–10060Loop-filter strength 0–100 for lossy frames.
-metadatacomma-separated tokensxmpCopy ICC and XMP from the GIF: all, none, icc, xmp (comma-separated).
-loop_compatibilityswitchoffLegacy loop-count handling for Chrome 62 and earlier; skips the GIF-to-WebP count adjustment.
-mtswitchoffUse multithreading where available.
-vswitchoffPrint conversion and mux diagnostics.
-quietswitchoffPrint nothing.
-h, -helpactionnot requestedPrint help.
-versionactionnot requestedPrint encoder, mux and libsharpyuv versions, then exit.
--actionnot requestedTreat the next argument as the input GIF and stop parsing options.