WebP
37c3317fd058; modified for Encode Wiki · CC BY-SA 4.0WebP 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 and weaknesses
Section titled “Strengths and weaknesses”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.
Support
Section titled “Support”| Browser | WebP |
|---|---|
| Chrome | 17+ (lossless and alpha from 23, animation from 32) |
| Edge | 18+ |
| Firefox | 65+ |
| Safari / iOS Safari | 14+ |
(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.
Encode with cwebp
Section titled “Encode with cwebp”cwebp reads PNG, JPEG, TIFF, WebP and PNM.
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.
| Goal | Command | Notes |
|---|---|---|
| Photo | cwebp -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 edges | add -sharp_yuv | Slower, more careful RGB→YUV 4:2:0 conversion; helps red text and thin coloured lines. |
| Lossless | cwebp -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 loss | cwebp -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 alpha | cwebp -q 80 -alpha_q 80 in.png -o out.webp | Alpha is coded separately and is lossless by default (-alpha_q 100); lower it to shrink soft masks. |
| Keep hidden RGB under transparency | add -exact | By default cwebp is free to change colours of fully transparent pixels to compress better. |
| Hit a size | cwebp -size 50000 in.png -o out.webp | Searches quality for a target byte size. -psnr 42 targets a PSNR instead. |
| Resize while encoding | cwebp -resize 1280 0 -q 80 in.png -o out.webp | 0 keeps the aspect ratio. |
With -lossless, -q no longer sets quality; it behaves as effort. Use -z instead.
Metadata and colour
Section titled “Metadata and colour”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.
Animation
Section titled “Animation”gif2webp -lossy -q 70 -m 6 input.gif -o output.webpimg2webp -loop 0 -lossy -q 70 -d 100 frame1.png frame2.png frame3.png -o animation.webpgif2webp 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.
Pitfalls
Section titled “Pitfalls”- Lossless is for graphics, screenshots and masters. A lossless WebP of a photograph is several times the size of a lossy one.
-q 100is 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.
Related pages
Section titled “Related pages”- 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.
Full option reference
Section titled “Full option reference”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.
cwebp parameter reference
Section titled “cwebp parameter reference”Complete cwebp 1.6.0 options and defaults
| Parameter and aliases | Type / accepted values | Default | Meaning and limits |
|---|---|---|---|
-preset | enum | default | Start from a tuned set (default, photo, picture, drawing, icon, text); resets other options, so put it first. |
-q | float 0–100 | 75 | Lossy quality 0–100, or lossless effort with -lossless. Disables -z. |
-m | integer 0–6 | 4 | Speed/size trade-off, 0 fast to 6 slowest and smallest. Disables -z. |
-z | integer 0–9 | not enabled | Lossless preset 0 (fast) to 9 (slowest); implies -lossless and is ignored if -q or -m is given. |
-lossless | switch | off | Encode with lossless VP8L instead of lossy VP8. |
-near_lossless | integer 0–100 | 100 (no preprocessing) | Lossless with pixel preprocessing: 100 is off, lower values discard more detail for smaller files. |
-hint | enum | default | Content hint for lossless coding: photo, picture or graph. |
-alpha_q | integer 0–100 | 100 | Alpha-plane quality 0–100; below 100 makes alpha lossy, independent of -q. |
-alpha_method | integer 0–1 | 1 | Alpha compression: 0 stores it raw, 1 uses lossless coding. |
-alpha_filter | enum | fast | Alpha-plane prediction filter: none, fast or best. |
-exact | switch | off | Keep RGB values under fully transparent pixels instead of zeroing them. |
-alpha_cleanup | switch | off (-exact is off) | Hidden obsolete flag that turns -exact off; has no other effect. |
-noalpha | switch | off | Discard the alpha channel. |
-blend_alpha | hex RGB | not enabled | Composite onto a hex RGB background (e.g. 0xffffff) and drop transparency. |
-segments | integer 1–4 | 4 | Number of VP8 segments, 1–4; fewer is faster but less adaptive. |
-sns | integer 0–100 | 50 | Spatial noise shaping 0–100; higher spends bits on perceptually important areas. |
-f | integer 0–100 | 60 | Loop-filter strength 0–100; 0 turns filtering off. |
-sharpness | integer 0–7 | 0 | Loop-filter sharpness 0 (most smoothing) to 7 (least). |
-strong | switch | on | Use the strong loop filter, which also filters chroma. |
-nostrong | switch | off | Use the simple loop filter, which is faster. |
-sharp_yuv | switch | off | Slower RGB-to-YUV conversion that preserves sharp color edges better. |
-partition_limit | integer 0–100 | 0 | Allow quality loss 0–100 so the first partition fits its 512 KiB limit. |
-size | nonnegative integer bytes | 0 (no target) | Target output size in bytes (lossy only); approximate. Raises -pass from 1 to 6. |
-psnr | nonnegative float dB | 0 (no target) | Target PSNR in dB (around 42 is typical); overrides -size. Lossy only. |
-pass | integer 1–10 | 1; becomes 6 for a size/PSNR target | Analysis passes 1–10 for size or PSNR targeting; more is slower and closer to target. |
-qrange | two integers | 0 100 | Limit the quality search to MIN MAX within 0–100. |
-af | switch | off | Experimental: adjust filter strength automatically. |
-jpeg_like | switch | off | Experimental: remap parameters so output size roughly matches JPEG’s, with less degradation. |
-pre | integer bitfield 0–7 | 0 | Experimental preprocessing bits: 1 segment smoothing, 2 dithering, 4 sharp YUV conversion. |
-mt | switch | off | Use multithreading where available. |
-low_memory | switch | off | Use less memory at the cost of speed. |
-s | two positive integers | not specified | Declare raw YUV420 input of WIDTH HEIGHT; not a resize. |
-crop | four integers x y width height | not enabled | Crop to X Y WIDTH HEIGHT before any resize. |
-resize | two nonnegative integers | not enabled | Resize to WIDTH HEIGHT after cropping; a zero dimension keeps the aspect ratio. |
-resize_mode | enum | always | When -resize applies: always, up_only or down_only. |
-metadata | comma-separated tokens | none | Copy metadata from the input: all, none, exif, icc, xmp (comma-separated). |
-o | path | none (encode without saving) | Output file; - writes to stdout. |
-d | PGM path | not enabled | Write the decoded result of the lossy encode to a PGM file for inspection. |
-map | integer | not enabled | Print a diagnostic map of encoder statistics; debugging only. |
-print_psnr | switch | off | Print PSNR of the encoded result against the source. |
-print_ssim | switch | off | Print SSIM of the encoded result against the source. |
-print_lsim | switch | off | Print local-similarity score of the encoded result. |
-short | switch | off | Print a condensed statistics summary. |
-quiet | switch | off | Print nothing. |
-v | switch | off | Print timing and extra diagnostics. |
-progress | switch | off | Print encoding progress as a percentage. |
-noasm | switch | off | Disable assembly optimizations (SSE, NEON); for debugging. |
-h, -help | action | not requested | Print the short help. |
-H, -longhelp | action | not requested | Print the full help. |
-version | action | not requested | Print the library and libsharpyuv versions, then exit. |
-- | action | not requested | Treat the next argument as the input file and stop parsing options. |
img2webp parameter reference
Section titled “img2webp parameter reference”Complete img2webp 1.6.0 options and defaults
| Parameter and aliases | Type / accepted values | Default | Meaning and limits |
|---|---|---|---|
-o | path | none (encode without saving) | Output animation file; - writes to stdout. |
-loop | nonnegative integer | 0 (infinite) | Animation loop count; 0 loops forever. |
-min_size | switch | off | Spend more time to minimize size; disables inserted keyframes. |
-kmin | integer | 2147483646 | Minimum frames between keyframes; the default effectively disables inserted keyframes. |
-kmax | integer | 2147483647 | Maximum frames between keyframes; 1 makes every frame a keyframe, 0 or less disables inserted ones. |
-mixed | switch | off | Pick lossy or lossless per frame automatically; per-frame -lossy and -lossless are then ignored. |
-near_lossless | integer 0–100 | 100 (no preprocessing) | Near-lossless preprocessing 0–100 for lossless frames; 100 is off. |
-sharp_yuv | switch | off | Slower RGB-to-YUV conversion with better edges, for lossy frames. |
-v | switch | off | Print frame order and timestamps. |
-h, -help | action | not requested | Print help. |
-version | action | not requested | Print encoder, mux and libsharpyuv versions, then exit. |
-d | positive integer milliseconds | 100 | Display time in milliseconds for this and following frames. |
-lossless | switch | on | Encode following frames losslessly (the default). |
-lossy | switch | off | Encode following frames lossily. |
-q | float 0–100 | 75 | Quality 0–100 for following frames; lossless effort when lossless. |
-m | integer 0–6 | 4 | Speed/size trade-off 0–6 for following frames; 6 is slowest and smallest. |
-exact | switch | off | Keep RGB under transparent pixels in following frames; compositing can still discard it. |
-noexact | switch | on | Allow following frames to zero RGB under transparent pixels (the default). |
gif2webp parameter reference
Section titled “gif2webp parameter reference”Complete gif2webp 1.6.0 options and defaults
| Parameter and aliases | Type / accepted values | Default | Meaning and limits |
|---|---|---|---|
-o | path | none (encode without saving) | Output WebP file; - writes to stdout. |
-lossy | switch | off | Encode lossy instead of the default lossless. |
-mixed | switch | off | Pick lossy or lossless per frame automatically. |
-near_lossless | integer 0–100 | 100 (no preprocessing) | Near-lossless preprocessing 0–100 for lossless frames; 100 is off. |
-sharp_yuv | switch | off | Slower RGB-to-YUV conversion with better edges, for lossy frames. |
-q | float 0–100 | 75 | Lossy quality 0–100, or lossless effort. |
-m | integer 0–6 | 4 | Speed/size trade-off 0–6; 6 is slowest and smallest. |
-min_size | switch | off | Spend more time to minimize size; disables inserted keyframes. |
-kmin | integer | 9 lossless; 3 lossy/mixed | Minimum frames between keyframes; libwebp may adjust inconsistent kmin/kmax pairs. |
-kmax | integer | 17 lossless; 5 lossy/mixed | Maximum frames between keyframes; 1 makes every frame a keyframe, 0 or less disables inserted ones. |
-f | integer 0–100 | 60 | Loop-filter strength 0–100 for lossy frames. |
-metadata | comma-separated tokens | xmp | Copy ICC and XMP from the GIF: all, none, icc, xmp (comma-separated). |
-loop_compatibility | switch | off | Legacy loop-count handling for Chrome 62 and earlier; skips the GIF-to-WebP count adjustment. |
-mt | switch | off | Use multithreading where available. |
-v | switch | off | Print conversion and mux diagnostics. |
-quiet | switch | off | Print nothing. |
-h, -help | action | not requested | Print help. |
-version | action | not requested | Print encoder, mux and libsharpyuv versions, then exit. |
-- | action | not requested | Treat the next argument as the input GIF and stop parsing options. |