All formats

Pillow

LanguagePython 3
LicenseMIT-CMU (permissive)
Repositorygithub.com/python-pillow/Pillow
DocumentationWebP in the Pillow docs
Depends onlibwebp (bundled in the PyPI wheels)
Read / writeyes / yes, lossy, lossless, alpha, animation, ICC, Exif, XMP

Pillow is the standard imaging library for Python. Its WebP plugin uses libwebp, which the binary wheels on PyPI include, so pip install pillow is enough on Windows, macOS and Linux. It supports every WebP feature: lossy and lossless encoding, alpha, animation (read and write) and metadata.

Installation#

Shell
pip install pillow

If you build Pillow from source, install libwebp-dev (Debian/Ubuntu) or webp (Homebrew) first.

Basic usage: convert to WebP#

Python
from PIL import Image

with Image.open("photo.jpg") as im:
    print(im.format, im.size, im.mode)
    im.save("photo.webp", quality=80, method=6)  # quality 0-100, method 0 (fast) .. 6 (smallest)

with Image.open("photo.webp") as im:
    im.save("photo.png")

How to save a lossless WebP#

Python
with Image.open("logo.png") as im:
    im.save("logo.webp", lossless=True, quality=100, method=6)  # for lossless, quality is the effort

Add exact=True to keep the RGB values of transparent pixels. For lossy images with alpha, alpha_quality=0..100 sets the alpha channel quality separately.

How to get WebP dimensions without decoding#

Image.open reads only the header; pixels are decoded on first access:

Python
with Image.open("in.webp") as im:
    print(im.size, im.mode, getattr(im, "n_frames", 1))

How to create an animated WebP#

Python
from PIL import Image

frames = [Image.open(f"frame{i}.png") for i in range(10)]
frames[0].save(
    "anim.webp",
    save_all=True,
    append_images=frames[1:],
    duration=100,   # ms per frame, or a list with one value per frame
    loop=0,         # 0 = forever
    quality=75,
    # lossless=True, minimize_size=True, allow_mixed=True are also accepted
)

Converting an animated GIF: Image.open("anim.gif").save("anim.webp", save_all=True).

How to read the frames of an animated WebP#

Python
from PIL import Image, ImageSequence

with Image.open("anim.webp") as im:
    print(im.n_frames, "frames, loop", im.info.get("loop"))
    for i, frame in enumerate(ImageSequence.Iterator(im)):
        print(i, frame.info.get("duration"), "ms")
        frame.convert("RGBA").save(f"frame{i}.png")

How to keep the ICC profile and Exif#

Pillow doesn’t copy metadata unless you pass it:

Python
with Image.open("photo.jpg") as im:
    im.save(
        "photo.webp",
        quality=80,
        icc_profile=im.info.get("icc_profile"),
        exif=im.info.get("exif", b""),
    )

Tips#