Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For most website images created or edited in Python, start with Pillow. It creates and processes raster images such as PNGs, composites and thumbnails. Choose CairoSVG when your input is SVG artwork that needs conversion to PNG or another supported output. They do different jobs, and can be used together when an SVG needs raster post-processing.

Choose the package by the image workflow

What you need to do Good starting point Check before shipping
Create or manipulate raster images, thumbnails, or composites Pillow Required format support, installed build dependencies, input size limits, and output encoding needs
Convert SVG artwork to PNG, PDF, PS, or SVG CairoSVG SVG feature coverage, Cairo/FFI dependencies, deployment platform, and license obligations
Convert an SVG, then edit the resulting pixels CairoSVG and, if needed, Pillow Validate the output and the dependencies of both packages in your target environment

This is a practical division of labor, not a performance ranking. Pillow is a general raster-image library; CairoSVG converts SVG documents. Neither is established as the universal best package for every website-image task.

Create website raster images with Pillow

Pillow is the maintained fork of PIL and provides a broad image-processing API. Use it to make a canvas, draw or composite image content, resize an existing raster, create a thumbnail, or save a supported format. It can also generate effects such as gradients and noise. The library handles pixels and file encoding; it does not make design decisions or provide a complete image-delivery service.

Install and create a PNG

Install Pillow in the Python environment that runs your script:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
python -m pip install Pillow

This example creates a simple 640-by-360 RGB image and writes it as a PNG:

from PIL import Image, ImageDraw

image = Image.new("RGB", (640, 360), color="#f2f5f9")
draw = ImageDraw.Draw(image)
draw.rectangle((32, 32, 608, 328), fill="#174ea6")
draw.text((56, 72), "Generated with Pillow", fill="white")
image.save("website-card.png", format="PNG")

The dimensions are pixels, and the explicit format makes the intended encoding clear. For transparency, create an image in an alpha-capable mode such as RGBA and save to a format that supports alpha, such as PNG or WebP where available in the installed build.

Resize, thumbnail, and composite

For an existing image, open it, convert to a mode suitable for the operation, and resize or composite it. Pillow’s thumbnail workflow preserves aspect ratio while fitting within a bounding box:

from PIL import Image

with Image.open("source.jpg") as source:
    source.thumbnail((800, 800))
    source.convert("RGB").save("thumbnail.jpg", format="JPEG", quality=85)

Unlike a fixed-size resize, thumbnail constrains the image to the requested box without enlarging it beyond its original size. JPEG has no transparency, so converting to RGB is appropriate when the output is a JPEG. Use an alpha-capable output if transparent areas must remain transparent.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For images generated in memory rather than saved directly to disk, Pillow supports file-like objects. A BytesIO buffer is useful when an application needs encoded bytes for another layer of its own response or storage workflow:

from io import BytesIO
from PIL import Image

image = Image.new("RGB", (320, 180), "white")
buffer = BytesIO()
image.save(buffer, format="PNG")
png_bytes = buffer.getvalue()

The buffer contains encoded image data; your web framework still needs to set the appropriate response content type and handle delivery.

Confirm formats in the deployed build

Do not assume every Pillow installation supports every image format identically. Consult the format handbook and verify the exact format support and system dependencies in the environment where the application will run. A script that works on a developer workstation can fail in a different deployment image if its installed build differs.

Convert SVG artwork with CairoSVG

SVG is vector artwork; a website workflow may need a raster PNG, or another output CairoSVG supports. CairoSVG is a Python 3 library and command-line tool for converting SVG 1.1 documents to PNG, PDF, PS, or SVG. It exposes Python functions such as svg2png and a CLI for file conversion.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Install and convert from Python

The package name for pip installation is cairosvg:

python -m pip install cairosvg

For an SVG file named logo.svg, a basic Python conversion is:

import cairosvg

cairosvg.svg2png(url="logo.svg", write_to="logo.png")

You can also invoke the command-line converter:

cairosvg logo.svg -o logo.png

Use the output type and options documented by CairoSVG for the target task. A simple conversion does not guarantee that every SVG feature will render exactly as it does in every browser or design tool.

Check platform dependencies, feature coverage, and licensing

CairoSVG documentation lists Linux, macOS, and Windows support, but installation can involve native components, including Cairo and FFI headers, and platform-specific setup. Confirm its current installation instructions for the operating system and deployment image you use rather than treating pip installation alone as proof that all dependencies are present.

Its documented SVG support has limitations: ICC color schemes, color interpolation and gamma correction for external raster images, and some SVG filters are not fully supported. Test representative artwork—especially assets using filters or color-management features—in the actual deployment environment. The documentation describes CairoSVG as LGPLv3 licensed; review the license terms for your distribution model.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use both when a workflow crosses vector and raster

If the source is SVG but later operations are pixel-based, convert with CairoSVG first and then open the PNG with Pillow. This keeps each step aligned to the package's documented role:

import cairosvg
from PIL import Image

cairosvg.svg2png(url="icon.svg", write_to="icon.png")
with Image.open("icon.png") as image:
    image.thumbnail((256, 256))
    image.save("icon-small.png", format="PNG")

This two-package example writes an intermediate file for clarity. A production pipeline can use in-memory streams if desired, but should still validate the rendered result and both packages' runtime dependencies.

Protect image-processing applications from risky inputs

If your application accepts images from users, treat decoding as work on untrusted input. Pillow documents a decompression-bomb warning and error behavior: a compact file can expand into a very large pixel image and consume excessive memory. Pillow uses a pixel-count threshold to detect this risk. Do not disable that safeguard casually; doing so removes a protection against oversized or hostile images. Set application-level upload and resource limits appropriate to your service, and decide deliberately how warnings and errors are handled.

Also validate expected formats and dimensions at the boundary of the application, and test failure handling with the same Pillow build used in production. Format support and behavior can depend on the installed build, so do not rely on assumptions based only on a developer machine.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot common failures

  • ModuleNotFoundError for PIL or cairosvg: Install the package into the same Python interpreter or virtual environment that runs the program. Pillow is installed as Pillow but imported from PIL; CairoSVG is installed as cairosvg.
  • CairoSVG install or import fails: Check the operating-system-specific Cairo and FFI requirements in its documentation. A Python package install may also need native libraries or build components.
  • An SVG looks different after conversion: Check whether the artwork uses features CairoSVG documents as limited, including some filters or color-management behavior. Test and, if necessary, revise or simplify the source SVG.
  • An image format cannot be opened or saved: Verify that the deployed Pillow build supports that format and has its required dependencies. Use the format handbook to check the format rather than assuming all builds are alike.
  • Large or untrusted input triggers a warning or error: Pillow's decompression-bomb protection is signaling a potentially resource-heavy image. Review the input limits and handling policy; do not switch off the protection without understanding the risk.
  • Generated output has unexpected transparency or color: Confirm the image mode and output format. For example, JPEG cannot preserve alpha transparency; choose an alpha-capable output when transparent pixels matter.

Capture a web page instead of generating an image

Pillow and CairoSVG create or convert image assets; they are not browser screenshot tools. If the actual task is to render a live web page and save what a visitor sees, you need a browser-based capture workflow rather than a raster drawing API.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server for developers. A single GET request can return a PNG, JPEG, WebP, or PDF. Here is the cURL call, with the API details in the ScreenshotNeo documentation:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Cookie banners are accepted like a visitor and removed, along with supported newsletter popups and chat widgets, before capture; each cleanup step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits cost nothing, and response headers identify the page verdict and billing status. Its MCP server lets AI agents using Claude, Cursor, or another MCP client take screenshots. The free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots.

Sign up free for 1,000 screenshots a month, with no card required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Can Python generate a PNG for a website?

Yes. Pillow can create a raster canvas and save it as PNG; CairoSVG can convert an SVG document to PNG.

Do I need Pillow to convert SVG to PNG?

No. CairoSVG is specifically documented for SVG conversion; Pillow is useful for raster processing after conversion.

Can I use Pillow and CairoSVG together?

Yes. Convert the SVG to a raster image with CairoSVG, then use Pillow for pixel operations such as resizing or compositing.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.