Back to Blog
Python

Convert JPG, PNG, and WebP with Python Pillow

python pillow convert jpg png webp image formats: Learn how to convert JPG, PNG, and WebP images with Python Pillow, including format-specific options, transparency ha...

PythonPillowImage ConversionWebPJPEGPNG
Illustration of converting image formats between JPG, PNG, and WebP using Python Pillow

python pillow convert jpg png webp image formats requires a clear understanding of the core syntax, runtime behavior, and practical implementation patterns demonstrated in the examples below.

When you need to convert JPG, PNG, or WebP images in Python, Pillow is the standard library for the job. The core workflow is simple: open an image with Image.open() and save it with a new format. But the details matter when you care about quality, transparency, metadata, or processing many files. This article walks through the conversion process and the decisions that come with each format.

The Basic Conversion Workflow

The simplest conversion looks like this:

from PIL import Image im = Image.open("input.jpg") im.save("output.png")

Pillow infers the output format from the file extension. The same pattern works for any combination of JPG, PNG, and WebP. If you need to specify the format explicitly, pass it as the second argument to save():

im.save("output", format="WEBP")

The format parameter is useful when the filename does not carry a clear extension or when you are writing to a file-like object.

Format-Specific Save Options

Each format accepts parameters that control compression and output quality. These are passed directly to save().

For JPEG:

im.save("output.jpg", quality=85, optimize=True, progressive=True)
  • quality controls the compression level, typically 1–95.
  • optimize spends extra time to produce a smaller file.
  • progressive writes a progressive JPEG, which loads in stages.

For PNG:

im.save("output.png", optimize=True, compress_level=9)

PNG uses lossless compression, so compress_level trades encoding time for file size. optimize also improves compression at the cost of speed.

For WebP:

im.save("output.webp", quality=80, lossless=False, method=4)
  • quality works like JPEG when lossless is False.
  • lossless=True produces a lossless WebP, which is useful for images with sharp edges or text.
  • method controls the compression effort, from 0 (fast) to 6 (slow, smaller output).

These options are not interchangeable. Passing a JPEG-only parameter to a PNG save is silently ignored, so keep them format-specific.

Handling Transparency and Color Modes

PNG and WebP support an alpha channel; JPEG does not. If you convert a transparent PNG to JPEG, Pillow will not fail, but the transparency is lost and the image may look wrong. You need to composite the image onto a solid background first:

from PIL import Image im = Image.open("transparent.png").convert("RGBA") background = Image.new("RGB", im.size, (255, 255, 255)) background.paste(im, mask=im.split()[3]) background.save("output.jpg")

The mask uses the alpha channel so only transparent areas show the white background. Without this step, the JPEG will contain black or undefined pixels in transparent regions.

When converting between formats that both support alpha, such as PNG to WebP, the alpha channel is preserved automatically. But be aware that some WebP encoders handle alpha differently, so verify the result if you rely on exact transparency.

Converting Multiple Images in a Batch

For a directory of images, loop over the files and convert each one. Use pathlib for clean path handling:

from pathlib import Path from PIL import Image input_dir = Path("images") output_dir = Path("converted") output_dir.mkdir(exist_ok=True) for src in input_dir.glob("*.png"): im = Image.open(src) dest = output_dir / (src.stem + ".webp") im.save(dest, "WEBP", quality=80)

This pattern keeps memory usage low because each image is opened, converted, and closed before the next one is processed. If you need to convert a large number of files, process them sequentially rather than loading all images into memory at once.

Preserving Metadata and Color Profiles

By default, Pillow does not carry over EXIF, ICC profiles, or other metadata when you save a converted image. To preserve them, copy the relevant entries from the source image's info dictionary:

im = Image.open("input.jpg") exif = im.info.get("exif") icc = im.info.get("icc_profile") im.save("output.webp", exif=exif, icc_profile=icc)

Not every format supports every metadata type. JPEG and WebP can store EXIF and ICC profiles, while PNG has its own metadata conventions. If the target format does not support a particular field, Pillow will ignore it or raise an error depending on the version. Test the output to confirm that the metadata you care about survived the conversion.

Choosing the Right Output Format

The decision between JPG, PNG, and WebP depends on the image content and the use case.

FormatCompressionTransparencyTypical Use
JPGLossyNoPhotographs, web images without alpha
PNGLosslessYesScreenshots, diagrams, images with text
WebPBothYesWeb delivery, smaller files than PNG or JPG

WebP often produces smaller files than JPEG at the same quality, but encoding is slower. PNG is the right choice when lossless output matters more than file size. JPEG remains a safe default for photographic content that does not need transparency.

Performance Considerations for Large Batches

Pillow loads the entire image into memory, so a batch conversion of large files can consume a lot of RAM. Process one image at a time and let the image object go out of scope before moving to the next. If you are converting to JPEG or WebP, the optimize and method options increase encoding time but reduce file size. There is no free lunch: smaller files cost CPU time.

For very large images, consider resizing before conversion if the final dimensions are known. That reduces memory usage and encoding time. If you need to convert thousands of files, parallelize with a process pool, but be aware that Pillow releases the GIL during some operations, so the speedup may not be linear.

python pillow convert jpg png webp image formats: Practical | RYUSLOG DEV