VMware ESXi and vSphere Cluster Management
Convert Images to Different Formats with Pillow
Learn how to use Python Pillow to open images and save them as JPEG, PNG, GIF, or PDF, including mode conversion, transparency, quality, and verification.
What Image Format Conversion Means
Image conversion means reading an existing source image, decoding its pixel data, and writing a new output image using a different image format, such as JPEG, PNG, GIF, or PDF.
The source filename identifies the file Pillow reads. The destination filename identifies where Pillow writes the converted file. The destination format controls how the image is encoded.
source.jpg -> Pillow reads and decodes the image -> output.pngA file extension is only the suffix of a filename, such as .jpg or .png. Renaming photo.jpg to photo.png does not convert the image. The file still contains JPEG data, and programs may fail to open it or interpret it correctly. A real conversion requires Pillow to decode the source and encode new output data.
Install Pillow
Pillow is a Python imaging library commonly imported through the PIL package namespace. Install it with:
python -m pip install PillowThese examples assume basic Python syntax, imports, file paths, and package installation.
Open an Image with Pillow
Import Image from PIL, then call Image.open(). This method loads an image from a filename or file-like object. Pillow generally identifies the source format from the image data rather than trusting the filename extension.
from PIL import Image
image = Image.open("source.jpg")
print(image.format)
print(image.size)
print(image.mode)The format property commonly reports a value such as JPEG or PNG. The size property contains the width and height as a tuple, and mode describes the pixel representation.
Save an Image in a New Format
Use the image object's save() method to create the output file. Its first argument is the destination path or filename. Pillow can often infer the output encoder from the destination extension.
from PIL import Image
image = Image.open("source.jpg")
image.save("output.png")Because the destination ends in .png, Pillow selects PNG output. The source extension and destination extension can be different.
You can also provide an explicit format. This is useful when the destination has no recognized extension, has an ambiguous extension, or when you want the encoder choice to be clear.
from PIL import Image
image = Image.open("source.jpg")
image.save("output.gif", format="GIF")In this example, format="GIF" requests the GIF encoder even though the destination filename already suggests it.
Common Pillow Output Formats
| Format | Typical use | Transparency support | Compression behavior | Important conversion consideration |
|---|---|---|---|---|
| JPEG | Photographs and images with many colors | No alpha-channel transparency | Usually lossy; often produces smaller files | Convert images with alpha or palette modes to RGB first |
| PNG | Graphics, screenshots, logos, and images needing transparency | Supports alpha transparency | Lossless; compression settings affect size and processing time | Usually preserves pixel data, but metadata and animation behavior still depend on the workflow |
| GIF | Indexed-color graphics and simple animation workflows | Limited transparency support | Indexed palette with a maximum of 256 colors per frame | Photographs, gradients, and detailed color may look degraded |
| Putting an image into a document-like output | Depends on the image and PDF workflow | PDF output is a container; the embedded image and options affect size | Support and mode requirements depend on the installed Pillow environment |
Practical Conversion Examples
Convert JPEG to GIF
This example demonstrates the basic open-and-save workflow with an explicit target format.
from PIL import Image
image = Image.open("photo.jpg")
image.save("photo.gif", format="GIF")GIF is most suitable when the result can tolerate an indexed palette. A photograph may lose smooth color gradients because GIF supports only a limited number of colors.
Convert PNG to JPEG
JPEG cannot store an alpha channel. If the PNG is an RGBA image, directly saving it as JPEG may raise an error or require a deliberate mode conversion. The simplest preparation is to discard transparency by converting to RGB:
from PIL import Image
image = Image.open("source.png").convert("RGB")
image.save("output.jpg", format="JPEG", quality=90)This creates a JPEG with no transparency. Transparent pixels cannot remain transparent in the JPEG file, so their appearance must be handled before saving.
Flatten Transparency onto a Background
If transparent pixels should appear against a particular color, composite the image onto a background before converting to RGB. White is a common choice, but select a color appropriate for the final design.
from PIL import Image
source = Image.open("transparent.png").convert("RGBA")
background = Image.new("RGB", source.size, "white")
background.paste(source, mask=source.getchannel("A"))
background.save("flattened.jpg", format="JPEG", quality=90)Use PNG instead when transparency must remain intact:
from PIL import Image
image = Image.open("transparent.png")
image.save("preserved.png", format="PNG")Save a Photograph as PNG
PNG uses lossless compression, so it does not discard pixel information in standard PNG encoding. However, a PNG version of a photograph is often larger than the JPEG version.
from PIL import Image
image = Image.open("photo.jpg")
image.save("photo.png")The dimensions normally remain the same, but the file size and encoding characteristics can change substantially.
Use Destination Extension Inference
When the destination has a recognized suffix, the extension can select the encoder:
from PIL import Image
image = Image.open("source.jpg")
image.save("output.png")If the destination has no recognized extension, provide the format explicitly:
from PIL import Image
image = Image.open("source.jpg")
image.save("converted-image", format="PNG")Save an Image as PDF
Pillow can save images as PDF when PDF support is available in the installed environment. RGB is a useful target mode for this workflow.
from PIL import Image
image = Image.open("source.png").convert("RGB")
image.save("output.pdf", format="PDF")PDF is an image-container output option rather than a direct replacement for every image format. Check the resulting file in the application that will consume it, especially when document layout, multiple pages, or print quality matters.
Image Modes and Compatibility
An image mode describes how Pillow represents each pixel:
RGBstores red, green, and blue color channels.RGBAstores red, green, blue, and an alpha channel for per-pixel transparency.Lstores grayscale or luminance values.Pstores palette indexes that refer to a color table.CMYKstores cyan, magenta, yellow, and black channels, commonly used in print workflows.
Destination formats impose restrictions. JPEG commonly expects RGB or grayscale data and cannot store an alpha channel. GIF uses an indexed palette. Some PDF workflows work most predictably with RGB or grayscale images.
| Source mode | Destination format | Potential issue | Recommended preparation |
|---|---|---|---|
| RGBA | JPEG | JPEG has no alpha-channel support | Composite onto a background, then convert to RGB |
| P or RGBA | GIF | GIF has a limited indexed palette and limited transparency behavior | Review the palette and transparency; convert or quantize deliberately when visual quality matters |
| RGB | PNG | Usually compatible; output may be larger than JPEG | Save directly and choose PNG compression options when needed |
| RGBA | PDF support and alpha handling vary by workflow | Convert to RGB when transparency is not required or flatten it first |
Use convert() when a destination requires a particular mode:
rgb_image = image.convert("RGB")
gray_image = image.convert("L")
rgba_image = image.convert("RGBA")Transparency and Format Limitations
The alpha channel stores transparency information. In an RGBA image, the A component controls how visible each pixel is. PNG can preserve this information, while JPEG cannot.
When JPEG output is required, choose one of two strategies:
- Discard transparency with
convert("RGB"), accepting the resulting background behavior. - Flatten the image against a selected background color before converting to RGB.
Do not assume that every destination preserves all source features. Conversion may alter transparency, metadata, color representation, palette details, or animation frames.
Quality and Output Options
save() accepts format-specific encoder options. The available options depend on the selected format and Pillow version.
- JPEG: The
qualityoption controls the balance between visual detail and file size. Higher values generally retain more detail but create larger files. Theoptimizeoption may help Pillow produce a more efficient JPEG encoding, with additional processing cost. - PNG: PNG is lossless, so compression does not intentionally discard pixel data. Compression settings can still affect output size and encoding time. A larger compression setting may require more processing.
- GIF: GIF is restricted to an indexed palette of up to 256 colors per frame. It can be useful for simple graphics and animation, but is usually a poor target for photographs.
from PIL import Image
image = Image.open("photo.png").convert("RGB")
image.save("photo.jpg", format="JPEG", quality=85, optimize=True)Quality settings are not universal across formats. Compare the output visually and measure file sizes using representative images rather than assuming one setting is best for every file.
Verify the Conversion
A successful call to save() does not by itself confirm that the output meets your requirements. Check that the file exists, reopen it, and inspect its format, dimensions, and mode.
from pathlib import Path
from PIL import Image
output_path = Path("output.png")
if not output_path.exists():
raise FileNotFoundError(output_path)
with Image.open(output_path) as result:
print("format:", result.format)
print("size:", result.size)
print("mode:", result.mode)Also inspect the image visually. Compare transparency, colors, sharpness, animation behavior, and metadata when those features matter. Dimensions often remain unchanged during a straightforward format conversion, but the target format can change how colors, palettes, alpha data, metadata, or multiple frames are represented.
Troubleshooting Conversion Problems
RGBA image cannot be saved as JPEG
Cause: JPEG does not support an alpha channel.
Resolution: Save as PNG to retain transparency, or composite against a background and convert to RGB before saving as JPEG.
Pillow cannot determine the output format
Cause: The destination has no recognized extension and no explicit format was provided.
Resolution: Use a recognized destination extension or pass format="PNG", format="JPEG", or another appropriate format to save().
The converted GIF looks degraded
Cause: GIF uses a limited indexed color palette.
Resolution: Use PNG or JPEG for images containing many colors, gradients, or photographic detail.
The output file is unexpectedly large or small
Cause: Formats use different compression methods, and image content strongly affects compression results.
Resolution: Select a format suited to the image and adjust supported options such as JPEG quality. Always inspect both visual quality and file size.
The image looks different after conversion
Cause: The target may not support the source's color mode, transparency, metadata, palette, or animation features.
Resolution: Inspect the source mode, convert deliberately, reopen the output, and test it in the viewer or downstream system that will use it.
Conversion Checklist
- Identify the source image and its actual format.
- Choose a destination format based on transparency, color complexity, animation, quality, and file-size needs.
- Open the source with
Image.open(). - Convert the image mode when the destination format requires it.
- Call
save()with a destination filename or an explicit format. - Set format-specific options such as JPEG quality when appropriate.
- Confirm that the output file exists.
- Reopen the output and inspect its format, dimensions, mode, and visual appearance.
For related Pillow work, see the image format conversion guide as a reference while applying these patterns to your own files.