Image Handling

This guide covers image embedding, external image export, and format selection for SVG output.

Overview

psd2svg extracts raster image data from PSD layers when needed. For pixel-based layers (photos, rasterized content, smart objects), Photoshop stores raw pixel data within the PSD file. psd2svg retrieves this pixel data and includes it in the SVG output.

Note that layer effects (drop shadows, glows, etc.) are not part of the stored pixel data. They are converted to SVG filters separately. The extracted images represent the base layer content before any effects or filters are applied.

These extracted images can be:

  • Embedded as base64-encoded data URIs within the SVG file

  • Exported as external files referenced by the SVG

Embedded vs External Images

Embedded Images

By default, images are embedded as base64-encoded data URIs:

from psd2svg import SVGDocument
from psd_tools import PSDImage

psdimage = PSDImage.open("input.psd")
document = SVGDocument.from_psd(psdimage)

# Save with embedded images (default)
document.save("output.svg")

Result: All images are embedded within the SVG as data:image/... URIs.

Pros:

  • Self-contained single file

  • No external dependencies

  • Works offline

  • Easy to share and distribute

Cons:

  • Larger file size (base64 adds ~33% overhead)

  • Cannot leverage browser caching

  • Difficult to update individual images

External Images

Export images to external files for better optimization:

from psd2svg import SVGDocument
from psd_tools import PSDImage

psdimage = PSDImage.open("input.psd")
document = SVGDocument.from_psd(psdimage)

# Save with external images in same directory
document.save("output.svg", image_prefix=".")
# => output.svg, 01.webp, 02.webp, ...

# Save with external images in subdirectory
document.save("output.svg", image_prefix="images/img")
# => output.svg, images/img01.webp, images/img02.webp, ...

Result: Images are saved as separate files and referenced by relative paths in the SVG.

Pros:

  • Smaller SVG file size

  • Images can be cached by browsers

  • Easy to replace or update images

  • Better for version control (text vs binary)

Cons:

  • Multiple files to manage

  • Requires proper directory structure

  • External dependencies

Command Line:

# Same directory as SVG
psd2svg input.psd output.svg --image-prefix .

# Subdirectory
psd2svg input.psd output.svg --image-prefix images/img

Image Path Behavior

The image_prefix parameter is interpreted relative to the output SVG file’s directory:

# If output.svg is in /path/to/output/file.svg
document.save("/path/to/output/file.svg", image_prefix=".")
# => Images in /path/to/output/ (same directory)

document.save("/path/to/output/file.svg", image_prefix="images/img")
# => Images in /path/to/output/images/ (subdirectory)

document.save("/path/to/output/file.svg", image_prefix="../shared/img")
# => Images in /path/to/shared/ (parent directory)

Image Formats

Supported Formats

psd2svg supports three image formats:

  • WebP - Modern format with excellent compression (default)

  • PNG - Lossless format with transparency support

  • JPEG - Lossy format, best for photographs (no transparency)

PNG

PNG provides lossless compression with transparency:

document.save("output.svg", image_prefix=".", image_format="png")

Pros:

  • Lossless compression

  • Universal support (all browsers, viewers)

  • Good for graphics with sharp edges

  • Supports transparency

Cons:

  • Larger file sizes than WebP

  • Slower compression/decompression

When to use: Maximum compatibility, archival, print, lossless requirement

JPEG

JPEG provides lossy compression for photographs:

document.save("output.svg", image_prefix=".", image_format="jpeg")

Pros:

  • Excellent compression for photos

  • Universal support

  • Small file sizes for photographic content

Cons:

  • Lossy compression (quality degradation)

  • No transparency support (alpha channel discarded)

  • Poor for graphics with sharp edges (artifacts)

When to use: Photographic content only, transparency not needed

Command Line:

# WebP
psd2svg input.psd output.svg --image-prefix . --image-format webp

# PNG
psd2svg input.psd output.svg --image-prefix . --image-format png

# JPEG
psd2svg input.psd output.svg --image-prefix . --image-format jpeg

Format Comparison

Example file sizes for a typical rasterized layer (1000x1000px with effects):

  • WebP: 45 KB (lossy), 120 KB (lossless)

  • PNG: 180 KB

  • JPEG: 60 KB (no transparency)

Choose based on your requirements:

  • Best compression: WebP lossy

  • Best quality: PNG or WebP lossless

  • Best compatibility: PNG

  • Photos only: JPEG

Image Encoding Utilities

The image_utils module provides utilities for encoding images:

from psd2svg.image_utils import encode_image
from PIL import Image

# Load an image
image = Image.open("photo.png")

# Encode as base64 data URI
data_uri = encode_image(image, format="webp")
# => "data:image/webp;base64,UklGRiQAAABXRUJQVlA4..."

# Use in SVG
svg = f'<image href="{data_uri}" />'

Supported Parameters:

  • format - Image format: “webp”, “png”, “jpeg” (default: “webp”)

  • quality - Quality for lossy formats (1-100, default: 95)

  • lossless - Use lossless compression for WebP (default: False)

Example: Custom Quality

from psd2svg.image_utils import encode_image
from PIL import Image

image = Image.open("photo.png")

# High quality WebP (95)
high_quality = encode_image(image, format="webp", quality=95)

# Lower quality WebP (75) for smaller size
low_quality = encode_image(image, format="webp", quality=75)

# Lossless WebP (larger but perfect quality)
lossless = encode_image(image, format="webp", lossless=True)

Best Practices

Web Delivery

For web applications, use external WebP images:

document.save(
    "output.svg",
    image_prefix="images/img",
    image_format="webp"
)

Benefits:

  • Smaller overall size

  • Browser can cache images

  • Faster initial page load

Offline/Email

For offline use or email, use embedded images:

document.save("output.svg")  # Embedded by default

Benefits:

  • Single file

  • No broken image links

  • Works without network

Performance Tips

Reduce File Size

  1. Use WebP format - 30-50% smaller than PNG

  2. External images - Avoids base64 overhead

  3. Optimize quality - Lower quality for acceptable results

  4. Minimize rasterization - Simplify effects where possible

# Optimized for web
document.save(
    "output.svg",
    image_prefix="images/img",
    image_format="webp"
)

Improve Load Performance

For web applications:

  1. Use external images - Enables browser caching

  2. Add image dimensions - Prevents layout shift

  3. Lazy load images - Load images as they enter viewport

  4. Use CDN - Serve images from CDN for faster delivery

Working with Images

The SVGDocument class provides access to extracted images through the images field:

from psd2svg import SVGDocument
from psd_tools import PSDImage

psdimage = PSDImage.open("input.psd")
document = SVGDocument.from_psd(psdimage)

# Access images dictionary
print(f"Number of images: {len(document.images)}")

# Iterate through images
for image_id, image in document.images.items():
    print(f"{image_id}: {image.size} {image.mode}")

Image IDs:

Images are keyed by auto-generated IDs (e.g., “image-1”, “image-2”, etc.) corresponding to the order they appear in the SVG.

Export and Load Images

Images can be exported and loaded separately:

from psd2svg import SVGDocument
from psd_tools import PSDImage

# Export document with images
psdimage = PSDImage.open("input.psd")
document = SVGDocument.from_psd(psdimage)
data = document.export()

# data = {
#     "svg": "<svg>...</svg>",
#     "images": {
#         "image-1": b"...",  # Encoded image bytes
#         "image-2": b"...",
#     },
#     "fonts": [...]
# }

# Load from exported data
restored = SVGDocument.load(data["svg"], data["images"], data["fonts"])

This is useful for serialization or transferring documents between processes.

Troubleshooting

Images Not Appearing

If images don’t appear in the SVG:

  1. Check file paths - Ensure external image files exist at the specified paths

  2. Verify relative paths - Paths must be relative to the SVG file location

  3. Check file permissions - Ensure image files are readable

  4. Validate SVG - Use an XML validator to check for errors

Large File Sizes

If file sizes are too large:

  1. Use external images - Remove base64 overhead

  2. Switch to WebP - 30-50% size reduction

  3. Lower quality - Adjust quality parameter

  4. Minimize effects - Simplify PSD effects to reduce rasterization

Poor Image Quality

If image quality is poor:

  1. Increase quality - Use higher quality setting (95-100)

  2. Use lossless - Switch to PNG or lossless WebP

  3. Check source - Verify PSD layer quality

  4. Use higher DPI - If rasterizing at low resolution