Limitations

While psd2svg strives to accurately convert PSD files to SVG format, there are inherent limitations due to differences between the Photoshop format and SVG capabilities.

Platform Support

Operating System Limitations

All Platforms: psd2svg works on Linux, macOS, and Windows with cross-platform text layer conversion support.

Text Layer Conversion:

  • Linux/macOS: Full support with fontconfig for font resolution and file path discovery

  • Windows: Full support with Windows registry for font resolution and file path discovery

Font Resolution Strategy:

psd2svg uses a hybrid font resolution approach:

  1. Static mapping: ~4,950 fonts mapped by PostScript name

    • 539 default fonts: Core fonts (Arial, Times New Roman, Noto fonts, Roboto, Adobe fonts, etc.)

    • 370 Hiragino variants: Japanese fonts with W0-W9 weight pattern (generated dynamically)

    • 4,042 Morisawa fonts: Professional Japanese typography fonts

    • Provides font family, style, and weight information

    • Works on all platforms without external dependencies

    • Enables text conversion to SVG <text> elements

    • JSON-based lazy loading for optimal performance

  2. Platform-specific font resolution (Linux/macOS/Windows):

    • Queries system fonts when file paths needed

    • Linux/macOS: fontconfig with CharSet API

    • Windows: Windows registry + fontTools cmap parsing

    • Used automatically by FontInfo.find_with_files() method during conversion

    • Enables font embedding with embed_fonts=True

Font Embedding:

Font embedding is fully supported on all platforms:

  • Static mapping: Provides font metadata (family, style, weight) for text conversion

  • Font file discovery: Uses platform-specific resolution to locate font files

  • Linux/macOS: fontconfig with CharSet API (fontconfig-py >= 0.4.0)

  • Windows: Windows registry + fontTools cmap parsing

  • Text conversion: Works without font files (uses SVG <text> with font-family names)

  • Font embedding: Automatically locates font files when embed_fonts=True

  • Font collections and variable fonts: Data URI embedding extracts each face of a TTC/OTC collection as its own font, and pins a named instance of a variable font to its axis coordinates. A file:// URL can select neither, so browsers use the first face at its default instance; resvg loads every face of a collection

Custom Font Mapping:

For fonts not in the default mapping (~4,950 fonts), provide custom mappings:

import json
from psd2svg import SVGDocument
from psd_tools import PSDImage

# Load custom font mapping
with open("fonts.json") as f:
    custom_fonts = json.load(f)

# Use in conversion
psdimage = PSDImage.open("input.psd")
document = SVGDocument.from_psd(psdimage, font_mapping=custom_fonts)

See the Font Handling guide for generating custom mappings.

SVG 1.1 Limitations

Blending Modes

SVG 1.1 does not support all Photoshop blending modes. Some blending modes have no SVG equivalent:

Unsupported blending modes:

  • Dissolve

  • Darker Color

  • Lighter Color

  • Vivid Light

  • Linear Light

  • Pin Light

  • Hard Mix

Linear Burn is converted to plus-darker and Linear Dodge to plus-lighter. However, majority of SVG renderers do not support these modes.

Exact only on layer effects:

Divide, Subtract, Linear Burn and Linear Dodge are reproduced exactly on Color, Gradient and Pattern Overlay effects, which synthesize their blend layer inside an SVG filter and so can be rewritten there.

Everywhere else – as a layer blending mode, or on a shape layer’s overlay effect, which paints a plain fill rather than a filter – they fall back to approximations and log at DEBUG. Divide and Subtract are approximated with difference, which inverts colors rather than approximating them; Linear Burn and Linear Dodge use plus-darker and plus-lighter as above. Flattening those layers in Photoshop is the reliable workaround.

Partially supported:

Some blending modes may render differently across browsers or may use approximations.

Workaround: Consider flattening layers with unsupported blending modes in Photoshop before conversion.

Gradient

SVG does not support all the gradient types available in Photoshop:

  • Angle

  • Reflected

  • Diamond

Also, gradient interpolation methods may differ. Classic interpolation is closest to SVG’s linear interpolation, but others may not match exactly:

  • Perceptual

  • Linear

  • Classic

  • Smooth

  • Stripes

Workaround: Use linear or radial gradients in Photoshop for best compatibility.

Filter Effects

The following filter effects are not supported:

  • Bevels and embossing

  • Satin

Other filter effects are approximations and may not exactly match Photoshop’s rendering:

  • Drop shadows and inner shadows

  • Inner and outer glows

  • Stroke

  • Color, gradient, and pattern overlays

The converter does its best to approximate these effects, but results may vary.

Adjustment Layers

Supported Adjustment Layers (Experimental):

  • Invert - Color inversion

  • Posterize - Reduces color levels

  • Threshold - Converts to black and white based on luminance threshold

  • Hue/Saturation - Adjusts hue, saturation, and lightness (supports colorize mode)

  • Exposure - Applies exposure, offset, and gamma correction

  • Brightness/Contrast - Adjusts brightness and contrast

  • Color Balance - Adjusts color balance for shadows, midtones, and highlights (with limitations, see below)

  • Curves - Applies tonal curve adjustments using SVG lookup tables

  • Levels - Adjusts input/output levels and midpoint gamma correction

Not Yet Implemented:

These are planned. Each is tracked by an issue.

  • Gradient Map - Maps grayscale to gradient colors (#368)

  • Channel Mixer - Remixes color channels with custom ratios (#369)

  • Photo Filter - Applies warming/cooling color filters; will be an approximation, as Photoshop’s “Preserve Luminosity” option cannot be expressed exactly (#370)

Cannot Be Represented in SVG Filters:

These are not planned. SVG offers feColorMatrix (a linear combination across channels) and feComponentTransfer (an independent one-dimensional lookup table per channel). The following adjustments need per-pixel decisions that neither primitive can express, so there is no faithful conversion to implement:

  • Black & White - Converts to grayscale with channel-specific controls. Which of the six range weights applies depends on the pixel’s hue, and that classification has no filter primitive. A fixed luminance matrix would discard the very sliders the user adjusted

  • Selective Color - Adjusts specific color ranges (CMYK-based). The same hue-classification problem

  • Vibrance - Adjusts saturation with skin tone protection. Nonlinear in each pixel’s existing saturation, which is not a per-channel quantity

  • Color Lookup - Applies 3D LUT color grading. feComponentTransfer is one-dimensional and per-channel, so only a separable LUT could be represented. Separately, psd-tools exposes no properties on ColorLookup, so the LUT data cannot be read from the PSD in the first place

Layers of these four types are omitted from the output: the rest of the document converts normally, but the adjustment is not applied. The converter logs the layer at DEBUG (-vv). Flatten these adjustments in Photoshop before conversion, or export a flattened version.

Technical Limitations:

Adjustment layers in Photoshop apply filters to the combined backdrop of all layers below them. SVG has fundamental architectural limitations that make this difficult to implement correctly:

  • CSS backdrop-filter: Would be ideal but does not work on SVG elements (only HTML elements)

  • SVG BackgroundImage: SVG filters’ BackgroundImage feature has poor browser support and is not available in most rasterizers (including resvg)

  • Current workaround: The experimental implementation wraps backdrop layers in a <symbol> and references it with a filtered <use>. The filter composites the adjustment’s blend mode, opacity, and layer mask with the backdrop itself. A clipped adjustment adds a second, unfiltered <use> underneath so the backdrop shows through outside the clipping base

Critical Limitation - Clipped Adjustments:

A clipped adjustment does not work correctly when the backdrop has transparency. Its two stacked <use> elements composite a semi-transparent backdrop twice.

Each clipped adjustment also doubles the render tree for every adjustment stacked above it, so a deep stack of them renders in exponential time and memory in Chromium.

Workaround: Flatten adjustment layers in Photoshop before conversion, or export a flattened version. This is the recommended approach for production use.

Color Balance Accuracy Limitations

The ColorBalance adjustment layer is implemented using SVG feComponentTransfer filters with 256-value lookup tables. Due to SVG’s independent channel processing architecture, global luminance-based tonal weighting cannot be perfectly emulated.

Implementation Approach:

  • Uses per-channel grayscale approximation (assumes R≈G≈B for luminance calculation)

  • Generates three separate lookup tables (one per RGB channel)

  • Applies Photoshop’s tonal range weighting formulas (shadows/midtones/highlights)

Expected Accuracy:

  • Perfect (100%): No-op adjustments (all parameters zero)

  • Excellent (95-99%): Moderate adjustments (±30 to ±70 range)

  • Good (85-95%): Extreme positive adjustments (+100 on all axes)

  • Moderate (65-75%): Extreme negative adjustments (-100 on all axes)

  • Best results: Balanced images with relatively similar RGB values

Known Limitations:

  • Global luminance: Cannot calculate true RGB luminance (0.299R + 0.587G + 0.114B) due to SVG’s per-channel processing

  • Neutral color preservation: Photoshop preserves pure neutral colors (white, gray, black) to avoid introducing unwanted color casts. The SVG implementation applies adjustments literally, which can tint neutral colors. For example, white (255, 255, 255) may become slightly tinted when Photoshop would keep it pure white.

  • Preserve Luminosity mode: Not fully supported - logs at DEBUG when enabled (luminosity=1)

  • Highly saturated colors: May have ~10-15% higher error for pure/saturated colors

  • Extreme negative adjustments: Severe color clipping when subtracting from low RGB values

  • File size: Adds ~2-3KB per ColorBalance layer (768 float values in LUTs)

Why This Is Acceptable:

ColorBalance is primarily used for subtle tonal color correction (e.g., warming shadows, cooling highlights), not extreme stylization. The grayscale approximation works well because:

  • Most images have relatively balanced RGB values in each tonal range

  • Weighted blending across tonal ranges smooths out approximation errors

  • Typical adjustments (±30 to ±70) achieve 95%+ accuracy

  • Visual differences are imperceptible for normal use cases

Technical Background:

SVG’s feComponentTransfer processes RGB channels independently, making it impossible to compute global luminance (which requires access to all three channels simultaneously). SVG filters like feColorMatrix can extract luminance, but feComposite arithmetic operations are limited to linear combinations and cannot perform the conditional, non-linear tonal weight calculations required by ColorBalance (e.g., if L < 0.33 then weight = (0.33 - L) / 0.33).

Workaround: For critical color accuracy requirements, flatten ColorBalance adjustments in Photoshop before conversion.

Smart Objects

Smart Object Features

  • Smart Object filters: Not supported

  • Embedded smart objects: Limited support

  • Linked smart objects: Not supported

Workaround: Rasterize smart objects in Photoshop before conversion if they contain unsupported features.

Text Layers

Text layers can be converted to SVG <text> elements (enable_text=True, default) or rasterized as images (enable_text=False).

Note: Text conversion is experimental and has limitations. For production use, test thoroughly with your target SVG renderers.

Native SVG Text Conversion

When enable_text=True (default), text layers are converted to native SVG <text> elements.

Supported Features:

  • Text content with multiple paragraphs and styled spans

  • Font family, size, weight (bold), and style (italic)

  • Faux bold (emitted as an outline thickening of the specified face) and faux italic

  • Font color (solid fill and stroke colors)

  • Horizontal and vertical writing modes

  • Text alignment (left, center, right, justify)

  • Text decoration (underline, strikethrough)

  • Text transformation (all-caps, small-caps)

  • Superscript and subscript with accurate positioning

  • Baseline shift for custom vertical positioning

  • Character alignment (mojisoroe) of mixed-size runs, by em box top, centre or bottom and by Roman baseline (point text; see below for bounding box text)

  • Letter spacing (tracking)

  • Kerning: Manual kerning adjustments (per-character pairs) and automatic metrics-based kerning (browser default)

  • Tsume (East Asian character tightening)

  • Ligatures (common ligatures and discretionary ligatures)

  • Line height (leading)

  • Horizontal and vertical text scaling (see Text Scaling Limitation below)

  • Position, rotation, and scaling transformations

  • Arc warp effects (experimental) - see Text Warp Effects below

Unsupported Features:

  • Gradient fills and pattern strokes (solid colors only)

  • Advanced OpenType features (e.g., stylistic sets, contextual alternates, positional forms)

  • Variable fonts and font variations

  • Character stroke width (strokes render at 1 user unit, and a stroked span cannot also carry the faux bold thickening)

  • Uniform alpha under faux bold: a translucent fill is composited twice where the thickening underlies it, darkening the stem interior

  • Faux italic slant (font-style: italic selects a real italic face where the family has one, instead of shearing the specified face)

  • Character alignment against the ideographic character face, StyleRunAlignment 1 and 4 (#440)

  • Character alignment of mixed-size runs in native bounding box text; enable the <foreignObject> text wrapping mode for those layers (#443)

  • Character alignment uses one em box descent for every face, the 88/12 box that Japanese faces are drawn to, because conversion reads no font metrics; faces built to other proportions are offset approximately

Text Warp Effects (Experimental):

Text layers with arc warp effects are converted to SVG <textPath> elements that follow curved paths. This feature is experimental and automatically enabled when arc warp is detected.

Supported Warp Types:

  • Arc warp (horizontal orientation only)

    • Positive values (+1 to +100): Arc bulging upward

    • Negative values (-1 to -100): Arc bulging downward

    • All intermediate warp values

Not Yet Supported:

  • Vertical arc warp

  • Other warp styles (Fish, Wave, Flag, etc.)

  • Warp perspective transforms

Technical Implementation:

Arc-warped text uses SVG <textPath> with dynamically generated arc paths. The arc radius is calculated using trigonometry:

  • scale = sin(π/2 × |warp_value|/100)

  • radius = (width + height) / 2 / scale

For extreme warp values (absolute value > 50), the textLength attribute is set to improve browser rendering consistency.

Renderer Compatibility:

  • ✅ Modern browsers: Chrome, Firefox, Safari, Edge (good support)

  • ✅ PlaywrightRasterizer: Full support via Chromium

  • ⚠️ ResvgRasterizer: Basic support, but may have rendering differences

  • ⚠️ Vector editors: Variable support (Inkscape, Sketch, Figma)

Known Limitations:

  • Height adjustment uses half box height; should ideally use baseline height

  • Only horizontal orientation supported

  • Text wrapping with warp not yet implemented

  • Unsupported warp styles fall back to straight line rendering

Example:

from psd2svg import SVGDocument
from psd_tools import PSDImage

# Text with arc warp is automatically converted to textPath
psdimage = PSDImage.open("curved_text.psd")
document = SVGDocument.from_psd(psdimage)
document.save("output.svg")

Fallback:

To disable text warp conversion and rasterize warped text instead:

document = SVGDocument.from_psd(psdimage, enable_text=False)

Text Wrapping Support:

Text wrapping for bounding box text (ShapeType=1) is supported using <foreignObject> with XHTML/CSS content. This feature is opt-in and disabled by default.

To enable text wrapping:

from psd2svg import SVGDocument
from psd2svg.core.text import TextWrappingMode
from psd_tools import PSDImage

psdimage = PSDImage.open("input.psd")
document = SVGDocument.from_psd(
    psdimage,
    text_wrapping_mode=TextWrappingMode.FOREIGN_OBJECT
)

foreignObject Renderer Compatibility:

  • ✅ Supported: Modern browsers (Chrome, Firefox, Safari, Edge)

  • ✅ Supported: PlaywrightRasterizer (Chromium-based rasterizer)

  • ❌ Not supported: ResvgRasterizer/resvg-py (the default rasterizer ignores foreignObject)

  • ❌ Not supported: Many SVG tools (PDF converters, design tools like Inkscape/Sketch/Figma)

Important Notes:

  • foreignObject text cannot be edited in vector graphics editors (appears as embedded HTML)

  • Centered and right-aligned foreignObject lines with non-zero tracking sit up to one letter spacing off their Photoshop position, because CSS counts the spacing that follows the last character of each line (#404)

  • A paragraph that mixes font sizes renders taller than its leading: CSS grows each line box to cover the smallest span on it, and the ascent and descent it would take to prevent that are not known when the markup is written (#427)

  • Text that does not fit its box renders outside it rather than being clipped, because the browser breaks lines where Photoshop does not and clipping would drop text Photoshop draws; the SVG canvas still bounds it, and an unbreakable word wider than the box overflows the same way. A layer that cannot fit however it wraps names its shortfall in an INFO message (#449)

  • Point text (ShapeType=0) always uses native SVG <text> elements, regardless of this setting

  • Default behavior (text_wrapping_mode=0) maintains backward compatibility with native SVG text

  • For web-only SVG display or browser-based rendering, foreignObject provides better text wrapping

  • For maximum compatibility, leave text wrapping disabled (default)

Paragraph Formatting:

The following paragraph formatting properties are supported in foreignObject mode:

  • ✅ First line indent (text-indent CSS)

  • ✅ Start/end indent (padding-left/padding-right CSS)

  • ✅ Space before/after (a single margin-block-start, so adjacent margins cannot collapse)

  • ⚠️ Hanging punctuation (hanging-punctuation CSS - Safari only)

Hanging Punctuation Browser Support:

  • ✅ Safari 10+

  • ❌ Chrome (not supported)

  • ❌ Firefox (not supported)

  • ❌ Edge (not supported)

The hanging-punctuation property is included in SVG output for future compatibility and Safari users, but will have no effect in other browsers.

Hyphenation Support:

Auto hyphenation (hyphens: auto) is supported in all modern browsers when the lang attribute is set (automatically set to en when hyphenation is enabled):

  • ✅ Chrome/Edge (supports hyphens: auto)

  • ✅ Firefox (supports hyphens: auto and hyphenate-limit-chars)

  • ✅ Safari (supports hyphens: auto and hyphenate-limit-chars)

However, hyphenate-limit-chars (which controls minimum word length and characters before/after hyphen) has limited support:

  • ❌ Chrome/Edge (not supported)

  • ✅ Firefox 43+ (supported)

  • ✅ Safari 17+ (supported)

PSD’s ConsecutiveHyphens and Zone properties have no CSS equivalents and are not converted.

Native SVG Limitation:

Paragraph indentation, hanging punctuation and hyphenation are only available in foreignObject mode. Space before/after is the exception: native SVG <text> elements carry it in the paragraph advance.

Font Requirements:

Text conversion requires fonts to be installed on the system. The converter uses fontconfig to resolve font names. If a font is not found:

  • One warning is logged per missing font

  • Text may fall back to a default system font

  • Results may differ from Photoshop’s rendering

Cross-platform font availability varies—test on your target deployment environment.

SVG Renderer Compatibility:

Rendering quality varies significantly across SVG renderers:

  • Chromium-based browsers (Chrome, Edge): Best support, including vertical text features

  • Firefox: Good support with minor differences

  • Safari: Acceptable support with some limitations

  • resvg (bundled rasterizer): Does not support:

    • text-orientation: upright for vertical writing mode

    • dominant-baseline alignment for vertical text

    • transform on <tspan> elements (SVG 1.1 limitation for horizontal/vertical scaling)

For best results with vertical text, use Chromium-based browsers for viewing or rendering.

Text Scaling Limitation:

Horizontal and vertical text scaling (horizontal_scale and vertical_scale in PSD) cannot be expressed on a <tspan>: transform on <tspan> is an SVG 2.0 feature that no major renderer supports (Chrome, Firefox, Safari, Edge and resvg all ignore it).

psd2svg therefore encodes the scaling in the font-size and in a transform on the <text> element, which every renderer honors:

  • Uniform scaling (horizontal_scale == vertical_scale) is applied to font-size and renders exactly.

  • Non-uniform scaling shared by the whole text layer is applied as a transform on the <text> element, anchored at the text origin so that alignment is preserved. This renders exactly as well.

  • Non-uniform scaling of individual spans cannot be applied to the <text> element, because the spans disagree. The font-size then carries the scale of the writing direction’s inline axis (horizontal_scale for horizontal text, vertical_scale for vertical text), and the remaining cross-axis scale is emitted as a transform on the <tspan> for SVG 2.0 renderers. When a paragraph holds a single span, that transform is optimized onto the <text> element, where it does render.

Impact:

Only the last case is approximate, and only where the residual transform stays on the <tspan>. Glyph advance widths, the position of the following characters and center/right alignment all match Photoshop, but renderers that ignore transform on <tspan> draw the run without the cross-axis scaling: glyphs of a horizontally scaled run are as tall as they are wide, and a vertically scaled run keeps its original height. An INFO message is logged during conversion.

Character alignment compounds this: a run aligned by its em box is positioned for the scaled cross-axis size it should have, so where the residual transform is ignored the run is drawn at its unscaled size in the position the scaled one would occupy.

The per-span fallback is also used when the <text> element cannot carry the scale: warped text (<textPath>, where the transform would distort the warp path), Justify All paragraphs (where the transform would stretch the textLength, and where lengthAdjust squeezes the scaled glyphs back to that length anyway), and paragraphs whose inline-axis anchor points differ. Multi-paragraph vertical text can use layer-wide scaling when all spans share the same scale and the paragraphs share an inline-axis anchor; its leftward column offsets lie on the unscaled cross axis. Warped text drops the cross-axis transform altogether, since text on a path has no baseline to anchor it at. Strong arc warps additionally set textLength="100%" on the <textPath> to match Photoshop, which stretches the run to the path length and so discards the inline-axis scaling as well.

Sideways runs in vertical text:

In vertical writing mode the inline axis is taken to be the vertical one, which holds for upright glyphs - all glyphs when the layer uses upright orientation, and CJK glyphs in the default mixed orientation. Latin runs in mixed orientation are rotated, so their advance follows horizontal_scale instead, and psd2svg scales them along the wrong axis. Their glyph proportions are still correct; only the advance widths of such runs are off by the ratio of the two scale factors.

Scaling the <text> element also scales the stroke width of stroked text and the geometry of layer effects, as any transform does.

Workarounds:

  1. Recommended: Use enable_text=False to rasterize text layers that scale individual spans

  2. Convert text to vector shapes (outlines) in Photoshop before conversion

  3. Apply the same scaling to the whole text layer, which converts exactly

Technical Background:

Rendering per-span non-uniform scaling exactly would require splitting the scaled spans into separate <text> elements (which do support transforms) and positioning them explicitly. That needs the rendered advance width of every preceding span, i.e. a font-metrics-based layout engine:

  • Position calculations - would require knowing rendered text widths without a layout engine

  • Line height calculations - scaled text affects vertical spacing in complex ways

  • Transform combination - when layers have their own transforms, matrix multiplication is required

  • Measurement drift - our metrics would have to match the renderer’s shaping (kerning, ligatures) exactly

textLength with lengthAdjust="spacingAndGlyphs" is not a solution either: it also needs the natural text width, and resvg does not advance the following text by it.

Given these complexities, the current implementation preserves the text layout and logs an INFO message instead.

Letter Spacing Differences:

Photoshop and SVG use different kerning algorithms, which may result in slight letter spacing differences:

Kerning Types:

  • Metrics kerning: Uses the font’s built-in kerning tables (kerning pairs)

  • Optical kerning: Adobe’s proprietary visual analysis algorithm that adjusts spacing based on glyph shapes

Photoshop Behavior:

  • Supports metrics, optical, and manual kerning modes

  • Japanese fonts can supply proportional metrics through palt and vpal

  • Optical kerning applies additional, shape-based adjustments computed by Photoshop

SVG/Browser Behavior:

  • Uses metrics kerning automatically via the CSS font-kerning: auto property (browser default)

  • Applies the font’s built-in kerning tables without optical adjustments

  • Enables the OpenType palt feature for horizontal Japanese text and vpal for vertical Japanese text when AutoKerning is enabled

  • Manual kerning adjustments from PSD files are preserved via SVG dx/dy attributes

The default resvg rasterizer does not interpret font-feature-settings. The palt and vpal adjustments therefore take effect in browser-based output, including the Playwright rasterizer, but not in resvg output. This support does not reproduce Photoshop’s proprietary optical kerning adjustments, so text that uses optical kerning can still have different glyph positions.

Even with a font that provides palt, browser output may differ at the end of a line or style run. The feature can change both a glyph’s placement and its advance, including for the final glyph. Photoshop’s automatic kerning and line-end Mojikumi rules need not apply the same terminal adjustment. As a result, the final glyph’s position or advance, and therefore the line’s total width, may differ from Photoshop even when the interior spacing looks right. Glyph outlines can still match. The corresponding behavior of vpal in vertical text has not been verified against a Photoshop fixture.

Why They Differ:

Optical kerning is a proprietary Adobe algorithm that cannot be replicated in SVG. The difference between optical and metrics kerning is expected and inherent to the different rendering engines. Most fonts have well-designed kerning tables, so the visual difference is typically minimal.

Workaround:

To compensate for kerning differences, you can use the text_letter_spacing_offset parameter:

from psd2svg import SVGDocument
from psd_tools import PSDImage

psdimage = PSDImage.open("input.psd")

# Apply a small negative offset to tighten letter spacing
document = SVGDocument.from_psd(
    psdimage,
    text_letter_spacing_offset=-0.015
)

# Or use a positive offset to loosen spacing
document = SVGDocument.from_psd(
    psdimage,
    text_letter_spacing_offset=0.01
)

The offset is in pixels and is added to all letter-spacing values. Typical values range from -0.02 to 0.02. You may need to experiment with different values depending on your fonts and target renderers. Because it changes spacing throughout the text, it cannot selectively correct a final-glyph palt adjustment.

Technical Notes:

  • The auto_kerning property reads the AutoKerning value from PSD EngineData

  • For Japanese runs with that value enabled, browser output requests palt or vpal; Photoshop optical kerning remains outside the scope of this mapping

  • SVG 1.1: kerning="auto" attribute enables kerning (default)

  • SVG 2.0/CSS: font-kerning: auto property enables kerning (browser default)

  • Manual kerning from PSD is always preserved regardless of the kerning mode

References:

Rasterized Text (Image Fallback)

When enable_text=False, the converter uses the rasterized preview image embedded in the PSD file.

This means:

  • Text is not editable in the resulting SVG

  • Text is not selectable or searchable

  • Scaling may reduce quality since text becomes a raster image

  • File size increases with embedded raster text

Since text is rasterized:

  • Text appears exactly as rendered in Photoshop, including all effects

  • Complex text effects (gradients, strokes, shadows) are preserved

  • All warp effects (arc, fish, wave, etc.) work correctly

  • Custom transformations work correctly

  • No font installation required on the target system

Workarounds:

  • If you need editable/scalable text: Convert text to vector shapes (outlines) in Photoshop before conversion

  • If you need smaller file sizes: Use external image export instead of embedded images

  • If text quality is critical: Export at higher DPI or use the rasterizer with appropriate scaling

3D and Special Features

The following Photoshop features are not supported:

  • 3D layers

  • Video layers

  • Animation timeline

  • Actions and scripts

  • Layer comps (only the active comp is converted)

Browser Compatibility

SVG Rendering Differences

SVG rendering quality varies significantly across browsers:

Best to Worst:

  1. Chrome/Chromium: Most accurate and feature-complete

  2. Firefox: Good support, minor differences

  3. Safari: Acceptable, some edge cases

  4. Edge: Generally good (Chromium-based)

Recommendation: Test your SVG output in target browsers to ensure acceptable quality.

Known Issues

  • Filter effects may render differently in different browsers

  • Some color profiles may not be preserved

  • Complex gradients may have slight variations

Performance Considerations

Large Files

  • Complex PSDs: Large files with many layers may result in large SVG files

  • Many embedded images: Embedding images as data URIs increases file size significantly

  • Processing time: Complex documents may take time to convert

Workaround:

  • Use external images instead of embedding: convert('in.psd', 'out.svg', image_prefix='img_')

  • Simplify layer structure in Photoshop when possible

  • Merge similar layers

Memory Usage

  • Large PSD files require significant memory to process

  • Multiple concurrent conversions may exhaust memory

Thread Safety

IMPORTANT: The psd2svg API is NOT thread-safe.

  • Do not share SVGDocument instances across threads

  • Do not perform concurrent operations on the same document

  • Use separate instances for parallel processing

Rasterizer Stability

resvg-py Error Handling

psd2svg requires resvg-py 0.5.0 or newer, which properly handles edge cases:

Exception Handling:

  • Malformed/corrupted SVG content → ValueError

  • Missing SVG files → ValueError

  • Empty/invalid SVG documents → ValueError

Error Recovery:

from psd2svg import SVGDocument

try:
    document = SVGDocument.from_psd(psd_image)
    rasterized = document.rasterize()
except ValueError as e:
    print(f"SVG rasterization failed: {e}")

See the Rasterizers documentation for more examples.

Legacy Note: Versions prior to psd2svg 0.11.0 (with resvg-py < 0.2.5) would crash (SIGABRT) instead of raising exceptions. Upgrade to the latest version for proper error handling.

Color Management

Color Space Limitations

  • CMYK: Converted without color management (see below)

  • Grayscale: Converted without color management (see below)

  • Lab color: Not supported

  • Color profiles: May not be fully preserved

  • Spot colors: Not supported

Workaround: Convert to RGB in Photoshop before conversion for best results.

CMYK and Grayscale Conversion

CMYK colors – text fills, shape fills, strokes and effect colors alike – are converted with the naive formula r = 255 * (1 - c) * (1 - k), where c and k are fractions between 0 and 1. Any ICC profile embedded in the PSD is ignored, so the result differs from the Photoshop composite, and saturated colors differ the most. For example, 100% cyan becomes #00ffff here, while Photoshop renders it as #00aeef through a U.S. Web Coated (SWOP) v2 profile.

Grayscale colors are converted by replicating the single stored component across red, green and blue, and the embedded gray profile is ignored the same way. The two places Photoshop stores that component disagree on its orientation: text colors carry a luminance, where 0 is black, while shape fill, stroke, effect and gradient stop colors carry a “% black”, where 100 is black. Either way, 50% gray becomes #808080 here, while Photoshop composites it as #959595 through a Dot Gain 20% profile.

Precision

Some color values may have minor precision differences due to format conversions.

Vector Shapes

Shape Limitations

  • Some custom shape tools may not translate perfectly

  • Vector masks have limitations

Workaround: Simplify paths in Photoshop if conversion issues occur.

Known Workarounds

For Best Results

  1. Simplify layer structure: Merge unnecessary layers

  2. Flatten effects: Rasterize complex effects

  3. Use RGB color mode: Convert from CMYK if needed

  4. Rasterize smart objects: If they contain unsupported features

  5. Test output: Always verify SVG output in target environment

  6. Use external images: For large PSDs with many raster elements

For Production Use

  1. Pre-process PSDs: Create conversion-friendly versions

  2. Automate testing: Test converted SVGs in target browsers

  3. Fallback strategy: Keep rasterized versions as fallback

  4. Version control: Track both PSD and SVG versions

Reporting Issues

If you encounter issues not listed here:

  1. Check if it’s a known limitation

  2. Test with simplified PSD files

  3. Report issues at: https://github.com/CyberAgent/psd2svg/issues

Include:

  • PSD file characteristics (size, layers, features used)

  • Error messages or unexpected behavior

  • Expected vs. actual output

  • Environment details (Python version, OS)