Scroll to navigation

SRC(1) psd-tools SRC(1)

NAME

src - src Documentation

psd-tools is a Python package for working with Adobe Photoshop PSD files as described in specification <https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/>.

INSTALLATION

Use pip to install the package:

pip install psd-tools


For advanced layer compositing features, install with the composite extra:

pip install psd-tools[composite]


This installs optional dependencies (aggdraw, scipy, scikit-image) required for:

  • Vector shape and stroke rendering
  • Gradient and pattern fills
  • Layer effects rendering

Basic compositing operations work without these dependencies by using cached previews or simple NumPy-based operations.

Note:

The composite extra may not be available on all platforms. Notably, Python 3.14 on Windows currently lacks aggdraw support.


Note:

In order to extract images from 32bit PSD files PIL/Pillow must be built with LITTLECMS or LITTLECMS2 support (apt-get install liblcms2-2 or brew install little-cms2)


GETTING STARTED

from psd_tools import PSDImage
psd = PSDImage.open('example.psd')
psd.composite().save('example.png')
for layer in psd:

print(layer)
image = layer.composite()


Check out the Usage <> documentation for more examples.

Usage

Command line

The package provides command line tools to handle a PSD document:

psd-tools export <input_file> <output_file> [options]
psd-tools show <input_file> [options]
psd-tools debug <input_file> [options]
psd-tools -h | --help
psd-tools --version


Example:

psd-tools show example.psd  # Show the file content
psd-tools export example.psd example.png  # Export as PNG
psd-tools export example.psd[0] example-0.png  # Export layer as PNG


Working with PSD document

psd_tools.api <#module-psd_tools.api> package provides the user-friendly API to work with PSD files. PSDImage <#psd_tools.PSDImage> represents a PSD file.

Open an image:

from psd_tools import PSDImage
psdimage = PSDImage.open('my_image.psd')


Most of the data structure in the psd-tools suppports pretty printing in IPython environment.

In [1]: PSDImage.open('example.psd')
Out[1]:
PSDImage(mode=RGB size=101x55 depth=8 channels=3)

[0] PixelLayer('Background' size=101x55)
[1] PixelLayer('Layer 1' size=85x46)


Internal layers are accessible by iterator or indexing:

for layer in psdimage:

print(layer)
if layer.is_group():
for child in layer:
print(child) child = psdimage[0][0]


Note:

The iteration order is from background to foreground, which is reversed from version prior to 1.7.x. Use reversed(psd) to iterate from foreground to background.


The opened PSD file can be saved:

psdimage.save('output.psd')


If the PSD File's layer structure was updated, saving it will update the ImageData section. However, the rendered image is likely different from the Photoshop's rendering due to the limited rendering support in psd_tools.

Working with Layers

There are various layer kinds in Photoshop.

The most basic layer type is PixelLayer <#psd_tools.api.layers.PixelLayer>:

print(layer.name)
layer.kind == 'pixel'


Some of the layer attributes are editable, such as a layer name:

layer.name = 'Updated layer 1'


psd_tools experimentally supports the creation of a new PixelLayer from a PIL object, the PIL image will be converted to the color mode of the PSD File given in parameter:

psdimage.create_pixel_layer(pil_image, name="Layer name")


To construct a layered PSD file from scratch:

psdimage = PSDImage.new(mode='RGB', size=(640, 480), depth=8)
layer = psdimage.create_pixel_layer(pil_image, name="Layer 1", top=0, left=0, opacity=255)
group = psdimage.create_group(name="Group 1")
group.append(layer)
psdimage.save('new_image.psd')


See the function documentation for further parameter explanations.

Group <#psd_tools.api.layers.Group> has internal layers:

for layer in group:

print(layer) first_layer = group[0]


Create a new group object.:

group = psdimage.create_group(name="Group name")
group.append(layer)


TypeLayer <#psd_tools.api.layers.TypeLayer> is a layer with texts:

print(layer.text)


ShapeLayer <#psd_tools.api.layers.ShapeLayer> draws a vector shape, and the shape information is stored in vector_mask and origination property. Other layers can also have shape information as a mask:

print(layer.vector_mask)
for shape in layer.origination:

print(shape)


SmartObjectLayer <#psd_tools.api.layers.SmartObjectLayer> embeds or links an external file for non-destructive editing. The file content is accessible via smart_object property:

import io
if layer.smart_object.filetype in ('jpg', 'png'):

image = Image.open(io.BytesIO(layer.smart_object.data))


SolidColorFill <#psd_tools.api.adjustments.SolidColorFill>, PatternFill <#psd_tools.api.adjustments.PatternFill>, and GradientFill <#psd_tools.api.adjustments.GradientFill> are fill layers that paint the entire region if there is no associated mask. Sub-classes of AdjustmentLayer represents layer adjustment applied to the composed image. See Adjustment layers <#adjustment-layers>.

Modifying the layer structure

The layer structure of a PSD object can be modified through methods emulating a python list.

The internal model of the psd layer structure will be automatically updated. Moving a layer from a PSD to another will also automatically convert the PixelLayer to the target psd's color mode.

The follwing are valid for both PSDImage and Group objects.

Set an item:

group[0] = layer


Add a layer or layers to a group:

group.append(layer)
group.extend(layers)


Insert a layer to a specific index in the group:

group.insert(3, layer)


Remove a layer from the a group:

group.remove(layer)


Pop a layer from the group:

layer = group.pop()


Emptying a layer group:

group.clear()


Get the index of a layer in the group:

index = group.index(layer)


Count the occurrences of a layer in a group:

count = group.count(layer)


Move a given list of layers in a newly created Group. If no parent group is given in parameter, the new group will replace the first layer of the list in the PSD structure:

group = psdimage.create_group(layer_list=[layer1, layer2, ...], name="New Group")


Some operations are available for all Layer objects.

Delete a layer from its layer structure:

group.remove(layer)


Layers can be moved from a group to another:

target_group.append(layer)


Layers can be moved within the group to change their order:

layer.move_up() # Will send the layer upward in the group
layer.move_down() # Will send the layer downward in the group


Exporting data to PIL

Export the entire document as PIL.Image:

image = psd.composite()
image.save('exported.png')


Export a single layer including masks and clipping layers:

image = layer.composite()


Export layer and mask separately without composition:

image = layer.topil()
mask = layer.mask.topil()


To composite specific layers, such as layers except for texts, use layer_filter option:

image = psd.composite(

layer_filter=lambda layer: layer.is_visible() and layer.kind != 'type')


Note:

Advanced compositing features require optional dependencies. Install with:

pip install psd-tools[composite]


These dependencies (aggdraw, scipy, scikit-image) are needed for:

  • Vector shapes and strokes
  • Gradient and pattern fills
  • Layer effects

Basic compositing works without them by using cached previews or simple pixel-based operations. If a feature requires missing dependencies, an ImportError with installation instructions will be raised.



Note that most of the layer effects and adjustment layers are not supported. The compositing result may look different from Photoshop.

Exporting data to NumPy

PSDImage or layers can be exported to NumPy array by numpy() method:

image = psd.numpy()
layer_image = layer.numpy()


Migrating to 1.12

psd-tools 1.12 makes composite dependencies optional to support more platforms and Python versions.

Breaking Change: Optional Composite Dependencies

The main breaking change in version 1.12 is that advanced compositing features now require optional dependencies that must be explicitly installed.

What changed:

  • Dependencies aggdraw, scipy, and scikit-image are now optional
  • Basic compositing with NumPy continues to work without these dependencies
  • Advanced features (vector masks, gradients, patterns, effects) require the composite extra

Migration steps:

If you use advanced compositing features, install with the composite extra:

pip install 'psd-tools[composite]'


Or install the dependencies separately:

pip install psd-tools aggdraw scipy scikit-image


What works without composite dependencies:

  • Reading and writing PSD files
  • Accessing layer information (names, dimensions, etc.)
  • Extracting raw pixel data with NumPy
  • Basic pixel layer compositing
  • Using cached layer previews

What requires composite dependencies:

  • Vector shape and stroke rendering
  • Gradient fills
  • Pattern fills
  • Layer effects rendering (drop shadows, strokes, etc.)

Error handling:

If you try to use advanced features without the dependencies installed, you'll see a clear error:

ImportError: Advanced compositing features require optional dependencies.
Install with: pip install 'psd-tools[composite]'


Why this change:

This change enables psd-tools to run on platforms where some composite dependencies are unavailable, particularly Python 3.14 on Windows where aggdraw is not yet available.

Module Structure Changes

Version 1.12 includes some internal refactoring that generally doesn't affect public APIs:

  • The PSD class moved from psd_tools.psd to psd_tools.psd.document (still importable from psd_tools.psd)
  • Utils module split into registry and bin_utils (internal change)
  • Composite module reorganized for better type safety (internal change)

These changes maintain backward compatibility for public imports.

Type Annotations

Version 1.12 adds comprehensive type annotations throughout the codebase. If you use type checkers like mypy, you may discover type errors in your code that were previously undetected. This is a good thing - the annotations help catch bugs earlier!

Migrating to 1.11

psd-tools 1.11 introduces stronger type-safety via annotation and new public APIs for layer creation. Now the following approach is possible to create a new layered document:

from PIL import Image
from psd_tools import PSDImage
image = Image.new("RGBA", (width, height))
psdimage = PSDImage.new(mode='RGB', size=(640, 480), depth=8)
layer = psdimage.create_pixel_layer(image, name="Layer 1", top=0, left=0, opacity=255)
psdimage.save('new_image.psd')


Version 1.11 introduces some breaking changes.

Layer creation now disables orphaned layers. They must be given a valid PSDImage object.

version 1.11.x:

image = Image.new("RGBA", (width, height))
psdimage.create_pixel_layer(psdimage, image)


version 1.10.x:

image = Image.new("RGBA", (width, height))
PixelLayer.frompil(None, image, parent=None)


The same layer cannot be shared between multiple container objects.

version 1.11.x:

layer = psdimage.create_pixel_layer(group, image)
psdimage.append(layer)  # This won't duplicate the layer.


Migrating to 1.10

psd-tools 1.10 has a few breaking changes.

Basic layer structure editing is supported in 1.10. You can add or remove a pixel layer, or change the grouping of layers.

psd-tools 1.10 drops compose module. Use composite instead.

version 1.10.x:

image = psd.composite()
layer_image = layer.composite()


Migrating to 1.9

psd-tools 1.9 switches to NumPy based compositing.

version 1.8.x:

psd = PSDImage.open(filename)
image = psd.compose()
layer = psd[0]
layer_image = layer.compose()


version 1.9.x:

psd = PSDImage.open(filename)
image = psd.composite()
layer = psd[0]
layer_image = layer.composite()


NumPy array API is introduced:

image = psd.numpy()
layer_image = layer.numpy()


Migrating to 1.8

There are major API changes in version 1.8.x.

Note:

In version 1.8.0 - 1.8.7, the package name was psd_tools2.


PSDImage

File open method is changed from load to open() <#psd_tools.PSDImage.open>.

version 1.7.x:

psd = PSDImage.load(filename)
with open(filename, 'rb') as f:

psd = PSDImage.from_stream(f)


version 1.8.x:

psd = PSDImage.open(filename)
with open(filename, 'rb') as f:

psd = PSDImage.open(f)


Layers

Children of PSDImage or Group is directly accessible by iterator or indexing.

version 1.7.x:

for layer in group.layers:

print(layer) first_child = group.layers[0]


version 1.8.x:

for layer in group:

print(layer) first_child = group[0]


In version 1.8.x, the order of layers is reversed to reflect that the index should not change when a new layer is added on top.

PIL export

Primary PIL export method is compose().

version 1.7.x:

image = psd.as_PIL()
layer_image = compose(layer)
raw_layer_image = layer.as_PIL()


version 1.8.x:

image = psd.compose()
layer_image = layer.compose()
raw_layer_image = layer.topil()


Low-level data structure

Data structures are completely rewritten to support writing functionality. See psd_tools.psd <#module-psd_tools.psd> subpackage.

version 1.7.x:

psd.decoded_data


version 1.8.x:

psd._record


Drop pymaging support

Pymaging support is dropped.

Changelog

1.12.0 (2025-11-17)

  • [packaging] Make composite dependencies optional via psd-tools[composite] extra (#525)
  • [api] Lazy-load advanced composite features (vector masks, gradients, effects) to avoid importing optional dependencies unless needed
  • [api] Basic numpy-based compositing works without scipy, scikit-image, or aggdraw
  • [api] Composite functionality raises ImportError with installation instructions only when advanced features are used
  • [api] Handle missing composite dependencies gracefully in PSDImage.save() (#532)
  • [packaging] Move aggdraw, scipy, and scikit-image to optional dependencies
  • [packaging] Keep numpy as core dependency for raw pixel data access
  • [refactor] Move PSD class to dedicated document module (#530)
  • [refactor] Reorganize composite module structure and add type safety (#524)
  • [refactor] Split utils module into registry and bin_utils (#537)
  • [refactor] Create shared API utils module (#538)
  • [refactor] Improve type annotations and standardize imports (#539)
  • [api] Add comprehensive type annotations to psd_tools package (#536)
  • [tests] Add comprehensive type annotations to test suite (#534, #535)
  • [tests] Add CI testing without composite dependencies (#533)
  • [docs] Enhance package and module docstrings with comprehensive documentation (#531)
  • [docs] Update installation instructions for optional composite support (#527)
  • [docs] Convert README to Markdown (#527)
  • [ci] Fix CI status badge in README (#523)
  • [ci] Fix ReadTheDocs build by adding Self import fallback
  • [ci] Fix Python 3.10 mypy compatibility (#526)
  • [chore] Remove unused deprecated decorator (#529)
  • [chore] Remove redundant MANIFEST.in file (#528)

Breaking change: Users who rely on advanced composite features (vector masks, gradient fills, pattern fills, stroke effects) must now install with pip install 'psd-tools[composite]' or install the optional dependencies separately. Basic pixel layer compositing continues to work with just numpy. This change enables support for Python 3.14 on Windows and other platforms where composite dependencies may not be available.

1.11.1 (2025-11-17)

[ci] Disable Python 3.14 on Windows due to aggdraw unavailability (#521)

1.11.0 (2025-11-09)

  • [api] Add public APIs for layer and group creation (#517)
  • [api] Type safety improvements (#516)
  • [api] Refactor psd_tools.api import dependencies (#515)
  • [api] Fix group blend mode returning None (#514)
  • [dev] Add Claude Code support (#511)
  • [api] Add type annotation to more APIs (#509, #510, #512)
  • [api] Add fill_opacity and reference_point attributes (#507, #508)
  • [psd] Improve pretty print of Subpath (#506)

1.10.13 (2025-10-02)

  • [docs] Fix incorrect method name in the usage (#504)
  • [api] Fix updated status flag (#503)
  • [api] Add tree traversal API (#502)
  • [psd] Fix crash when reading malformed Levels record (#501)

1.10.12 (2025-09-25)

  • [api] Drop docopt dependency (#498)
  • [api] Remove unused imports (#497)
  • [api] Fix stacked clip layer handling (#496)

1.10.11 (2025-09-24)

  • [tests] Drop python2 compatibility code (#494)
  • [api] Fix clip layer handling (#493)
  • [psd] Workaround CAI tagged block reconstruction (#492)

1.10.10 (2025-09-18)

  • [api] Fix clipping with stroke composite (#489)
  • [ci] Fix documentation build (#486, #487)
  • [ci] Introduce ABI3 wheels (#483, #485)
  • [api] Fix PyCMSError in composite (#484)
  • [api] Fix ImageMath deprecation warning (#482)

1.10.9 (2025-08-07)

[psd] Allow linked layer version 8 (#476)

1.10.8 (2025-06-06)

  • [ci] Update CI configuration (#471)
  • [psd] Workaround levels adjustment layer parsing (#470)
  • [psd] Support CAI, GenI, OCIO tagged blocks (#469)

1.10.7 (2025-02-25)

[psd] Fix missing gradient method (#465)

1.10.6 (2025-02-18)

[security] Update pillow dependency (#462)

1.10.5 (2025-02-18)

[security] Update pillow dependency (#461)

1.10.4 (2024-11-25)

[api] Allow Path objects for PSDImage open (#452)

1.10.3 (2024-11-20)

  • [psd] Fix data corruption by irregular OSType (#449)
  • [api] Add type annotation to the high-level APIs (#448)

1.10.2 (2024-10-23)

  • [api] Add channel info via DisplayInfo (#443)
  • [api] Support layer locking (#442)

1.10.1 (2024-10-10)

  • [api] Fix artboard creation (#438)
  • [api] Fix layer conversion issue (#435)

1.10.0 (2024-09-26)

  • [api] Support basic layer structure editing (#428)
  • [api] Drop deprecated compose module (#432)

1.9.34 (2024-07-01)

  • [api] Support text type property (#419)
  • [psd] Improve RLE decoding error handling (#417)

1.9.33 (2024-06-14)

  • [psd] Raise IO error instead of assertion (#413)
  • [api] Add a new property to SmartObject: transform_box (#412)
  • [ci] Migrate code formatter to ruff (#408)

1.9.32 (2024-05-01)

[psd] Fix incorrect group divider handling (#399)

1.9.31 (2024-02-26)

[psd] Reworked packbits/rle algorithms (#392)

1.9.30 (2024-01-06)

[ci] Fix missing pyx file in sdist (#386)

1.9.29 (2024-01-04)

  • [ci] Update CI configuration (#383)
  • [dev] Migrate the builder to pyproject.toml
  • [dev] Update linter and formatter to pysen
  • [dev] Deprecate tox
  • [psd] Add new color sheet (#380)
  • [psd] Fix transparency check (#370)

1.9.28 (2023-07-04)

[psd] Add alternate 8ELE signiture for 8BIM tagged block (#367)

1.9.27 (2023-06-27)

[composite] Fix regression by #361 (#364)

1.9.26 (2023-06-21)

  • [composite] Read HSB colors in RGB and CMYK color modes (#361)
  • [ci] Update CI configuration (#362)

1.9.25 (2023-06-19)

[composite] Fix hue, sat, and vivid light (#359)

1.9.24 (2023-01-17)

  • [psd] Support float RGB values (#350)
  • [psd] Workaround stroke class ID (#346)
  • [ci] Update CI configuration (#347)
  • [composite] Fix group clipping (#336)

1.9.23 (2022-09-26)

[api] Add bbox invalidation when toggling layer visibility (#334)

1.9.22 (2022-09-09)

[psd] Add support for v3 gradient map adjustment layer (#330)

1.9.21 (2022-06-18)

  • [api] Fix incorrect has_effects behavior (#322)
  • [composite] Improve blending numerical stability (#321)
  • [composite] Improve non-RGB modes and transparency (#319, @Etienne-Gautier)
  • [psd] Workaround assertion error in broken file (#320)

1.9.20 (2022-05-16)

  • [ci] Update CI configuration (#313 #314)
  • [composite] Fix composite errors (#312)
  • [psd] Suppress vowv tagged blocks (#306)

1.9.19 (2022-04-15)

[composite] Fix rasterized shape composite (#301 #302)

1.9.18 (2021-08-20)

  • [api] Fix missing effect attributes (#284)
  • [package] Support additional platforms (i686, aarch64, universal2, win32)
  • [package] Drop py36 support

1.9.17 (2021-01-15)

[api] Fix incorrect fill layer parse (fix #254)

1.9.16 (2020-09-24)

  • [package] Drop py27 and py35 support
  • [psd] Workaround Enum bug (fix #241)
  • [composite] Fix transparency issue (fix #242)
  • [composite] Fix mask disable flag (fix #243)
  • [api] Add workaround for creating PSB (fix #246)
  • [api] Fix incorrect adjustment parse (fix #247)

1.9.15 (2020-07-17)

  • [composite] Fix ignored clip layers for groups.
  • [composite] Fix out-of-viewport stroke effect.

1.9.14 (2020-07-10)

  • [api] Bugfix for PSDImage composite layer_filter option.
  • [api] Bugfix for transparency and alpha distinction.
  • [psd] Rename COMPOSITOR_INFO.
  • [composite] Fix stroke effect target shape.

1.9.13 (2020-05-25)

[api] Bugfix for PSDImage init internal.

1.9.12 (2020-05-20)

[psd] Bugfix for CurvesExtraMarker read.

1.9.11 (2020-05-01)

[composite] Fix layer check.

1.9.10 (2020-04-21)

[psd] Fix engine data parser.

1.9.9 (2020-03-30)

[composite] Fix stroke effect argument.

1.9.8 (2020-03-18)

  • [composite] Fix incorrect fill opacity handling in compositing.
  • [composite] Fix incorrect alpha for patterns.

1.9.7 (2020-03-17)

  • [composite] Fix path operation for merged components.
  • [composite] Fix vector mask compositing condition.

1.9.6 (2020-03-16)

[composite] Fix incorrect alpha channel handling in composite.

1.9.5 (2020-03-11)

  • [api] Add ignore_preview option to PSDImage.composite.
  • [composite] Improve stroke effect composition for vector masks.
  • [composite] Avoid crash when there is an erroneous subpath.
  • [composite] Workaround possible divide-by-zero warn in stroke composition.
  • [composite] Fix incorrect pattern transparency handling.
  • [composite] Fix ignored effects in direct group composition.
  • [composite] Fix incorrect opacity handling for clip layers.

1.9.4 (2020-03-11)

[compression] Security fix, affected versions are 1.8.37 - 1.9.3.

1.9.3 (2020-03-10)

  • [composite] Fix memory corruption crash for pattern data in PSB files.
  • [psd] Add image data pretty printing.

1.9.2 (2020-03-03)

  • [psd] Add missing resource ID.
  • [psd] Fix pretty printing regression.
  • [psd] Fix big tag key for linked layers.
  • [psd] Support frgb tag.
  • [psd] Support sgrp metadata key.
  • [psd] Support patt tag.
  • [psd] Workaround unknown engine data.

1.9.1 (2020-02-28)

[psd] Minor bugfix.

1.9.0 (2020-02-26)

  • [composite] Implement NumPy-based compositing functionality.
  • [composite] Support blending modes other than dissolve.
  • [composite] Support blending in RGB, CMYK, Grayscale.
  • [api] Introduce NumPy array export method.
  • [api] Drop deprecated methods from v1.7.x such as as_PIL.
  • [api] Deprecate compose method.
  • [compression] Rename packbits to rle.
  • [compression] Improve RLE decode efficiency.
  • [tests] Additional compositing tests.

1.8.38 (2020-02-12)

[composer] fix crash when gradient fill is in stroke.

1.8.37 (2020-02-07)

  • [compression] Remove packbits dependency and introduce cython implementation.
  • [deploy] Move CI provider from Travis-CI to Github Actions.
  • [deploy] Start distributing binary wheels.

1.8.36 (2019-12-26)

[psd] add safeguard for malformed global layer mask info parser.

1.8.35 (2019-12-26)

  • [api] remove duplicate has_mask() definition.
  • [composer] fix empty effects check.

1.8.34 (2019-11-28)

  • [api] fix compose() arguments.
  • [psd] fix attrs version dependency.

1.8.33 (2019-11-28)

  • [api] add include_invisible option to Group.extract_bbox.
  • [psd] fix deprecated attrs api.

1.8.32 (2019-11-28)

[psd] fix 16/32 bit file parsing bug introduced in 1.8.17.

1.8.31 (2019-11-27)

  • [psd] bugfix reading psb.
  • [psd] bugfix reading slices resource.
  • [security] update dependency to pillow >= 6.2.0.

1.8.30 (2019-09-24)

[psd] workaround for reading less-than-4-byte int in malformed psd files.

1.8.29 (2019-09-10)

[composer] fix vector mask bbox in composition.

1.8.28 (2019-09-09)

[api] fix Effects.__repr__() when data is empty.

1.8.27 (2019-08-29)

  • [api] accept encoding param in PSDImage.open and PSDImage.save.
  • [deploy] bugfix travis deployment condition.

1.8.26 (2019-08-28)

[composer] support group mask.

1.8.25 (2019-08-07)

  • [api] change return type of PSDImage.color_mode to enum.
  • [api] support reading of bitmap color mode.
  • [api] support channel option in topil() method.

1.8.24 (2019-07-25)

[composer] experimental support of commutative blending modes.

1.8.23 (2019-06-24)

  • [composer] fix clipping on alpha-less image;
  • [composer] fix stroke effect for flat plane;
  • [composer] workaround for insufficient knots;
  • [composer] fix for custom color space.

1.8.22 (2019-06-19)

  • fix pass-through composing bug;
  • fix alpha blending in effect;
  • fix vector mask composition;
  • experimental support for shape stroke;
  • experimental support for stroke effect.

1.8.21 (2019-06-18)

  • change effect property return type from str to enum;
  • improve gradient quality;
  • support fill opacity and layer opacity;
  • add tmln key in metadata setting.

1.8.20 (2019-06-13)

support gradient styles.

1.8.19 (2019-06-11)

  • fix broken psd_tools.composer.vector module in 1.8.17;
  • experimental support for color noise gradient;
  • bugfix for clip masks;
  • bugfix for CMYK composing.

1.8.17 (2019-06-05)

  • move psd_tools.api.composer module to psd_tools.composer package;
  • support 19 blending modes in composer;
  • support fill opacity;
  • fix image size when composing with masks;
  • rename TaggedBlockID to Tag;
  • rename ImageResourceID to Resource;
  • add bytes mixin to Enum constants;
  • replace Enum keys with raw values in psd_tools.psd.base.Dict classes.

1.8.16 (2019-05-24)

  • fix broken group compose in 1.8.15;
  • fix missing pattern / gradient composition in vector stroke content.

1.8.15 (2019-05-23)

  • coding style fix;
  • fix compose() bbox option.

1.8.14 (2019-04-12)

  • add dependency to aggdraw;
  • support bezier curves in vector masks;
  • support path operations;
  • fix compose(force=True) behavior;
  • fix default background color in composer;
  • improve pattern overlay parameters support;
  • fix gradient map generation for a single stop.

1.8.13 (2019-04-05)

  • fix engine_data unknown tag format;
  • fix compose for extra alpha channels;
  • workaround for pillow 6.0.0 bug.

1.8.12 (2019-03-25)

add apply_icc option in pil io.

1.8.11 (2019-03-14)

  • introduce terminology module;
  • reduce memory use in read;
  • add main testing.

1.8.10 (2019-02-27)

fix PSB extn key size bug.

1.8.9 (2019-02-21)

  • documentation updates;
  • introduce Artboard class.

1.8.8 (2019-02-20)

  • revert package name to psd_tools;
  • prepare merging to the main repo.

1.8.7 (2019-02-15)

minor bugfix.

1.8.6 (2019-02-14)

  • change _psd pointer in PSDImage;
  • add version property;
  • support fill effects in composer.

1.8.5 (2019-02-05)

  • change tagged block/image resource singleton accessor in user API;
  • add documentation on iterator order;
  • fix export setting 1 big key config;
  • fix computer info big key config.

1.8.3 (2019-02-01)

  • add channel size checking in topil;
  • add mlst metadata decoding;
  • fix key collision issue in descriptor;
  • performance improvement for packbit encoding/decoding;
  • drop cython dependency in travis config;
  • implement thumbnail, is_group, and parent methods in PSDImage.

1.8.0 (2019-01-24)

  • major API changes;
  • package name changed to psd_tools2;
  • completely rewritten decoding subpackage psd_tools2.psd;
  • improved composer functionality;
  • file write support;
  • drop cython compression module and makes the package pure-python;
  • drop pymaging support.

1.7.30 (2019-01-15)

  • composer alpha blending fix;
  • documentation fix.

1.7.28 (2019-01-09)

support cinf tagged block.

1.7.27 (2018-12-06)

add missing extra image resource block signatures.

1.7.26 (2018-12-03)

move psd_tools tests under tests/psd_tools.

1.7.25 (2018-11-27)

fix alpha channel visibility of composed image.

1.7.24 (2018-11-21)

fix unit rectangle drawing size.

1.7.23 (2018-11-20)

fix ignored visibility in bbox calculation.

1.7.22 (2018-10-12)

  • drop py34 support;
  • fix tobytes deprecation warning.

1.7.21 (2018-10-10)

fix gradient descriptor bug.

1.7.20 (2018-10-09)

  • fix coloroverlay bug;
  • fix gradient angle bug;
  • fix curves decoder bug.

1.7.19 (2018-10-02)

fix descriptor decoder.

1.7.18 (2018-09-26)

  • add shape rendering in compose();
  • add grayscale support.

1.7.17 (2018-09-21)

fix has_pixel() condition.

1.7.16 (2018-08-29)

  • fix fill opacity in compose();
  • workaround for broken PrintFlags.

1.7.15 (2018-08-28)

fix color overlay issue in compose().

1.7.14 (2018-08-24)

fix verbose arg for python 3.7 compatibility.

1.7.13 (2018-08-10)

  • fix has_pixel() for partial channels;
  • support color overlay in compose().

1.7.12 (2018-06-25)

fix mask rendering in compose (Thanks @andrey-hider and @nkato).

1.7.11 (2018-06-11)

unicode bugfixes.

1.7.10 (2018-06-06)

  • fix descriptor decoding errors;
  • minor bugfixes.

1.7.9 (2018-06-05)

  • fix UnicodeError in exif;
  • workaround for irregular descriptor name;
  • add undocumented extn tagged block decoding;
  • move duplicated icc module to subpackage;
  • support PIL rendering with extra alpha channels.

1.7.8 (2018-05-29)

  • update documentation;
  • fix PEP8 compliance;
  • rename merge_layers to compose.

1.7.7 (2018-05-02)

fix white background issue in as_PIL().

1.7.6 (2018-04-27)

  • add quality testing;
  • fix disabled mask.

1.7.5 (2018-04-25)

  • fix has_mask() condition;
  • add mask composition in merge_layers();
  • fix mask display.

1.7.4 (2018-03-06)

fix infinity loop in print_tree().

1.7.3 (2018-02-27)

  • add vector origination API;
  • fix shape and vector mask identification;
  • change enum name conversion;
  • update docs.

1.7.2 (2018-02-14)

  • add adjustments API;
  • add mask API;
  • bugfix for tagged_blocks decoders.

1.7.1 (2018-02-08)

  • add mask user API;
  • add layer coordinate user API;
  • add vector mask and vector stroke API;
  • cleanup user API;
  • add automatic descriptor conversion.

1.7.0 (2018-01-25)

  • cleanup user API organization;
  • remove json encoder api;
  • make cli a package main.

1.6.7 (2018-01-17)

  • workaround for anaconda 2.7 pillow;
  • bbox existence checkf.

1.6.6 (2018-01-10)

  • experimental clipping support in merge_layer();
  • revert as_PIL() in AdjustmentLayer.

1.6.5 (2017-12-22)

Small fix for erroneous unicode path name

1.6.4 (2017-12-20)

  • Add all_layers() method;
  • Add _image_resource_blocks property;
  • Add thumbnail() method.

1.6.3 (2017-09-27)

  • documentation updates;
  • github repository renamed to psd-tools2;
  • AdjustmentLayer fix.

1.6.2 (2017-09-13)

  • layer class structure reorganization;
  • add Effects API;
  • add TypeLayer API methods.

1.6 (2017-09-08)

  • PSDImage user API update;
  • user API adds distinct layer types;
  • Sphinx documentation.

1.5 (2017-07-13)

  • implemented many decodings of image resources and tagged blocks;
  • implemented EngineData text information;
  • user API for getting mask and patterns;
  • user API to calculate bbox for shape layers;

1.4 (2017-01-02)

  • Fixed reading of layer mask data (thanks Evgeny Kopylov);
  • Python 2.6 support is dropped;
  • Python 3.6 support is added (thanks Leendert Brouwer);
  • extension is rebuilt with Cython 0.25.2.

1.3 (2016-01-25)

  • fixed references decoding (thanks Josh Drake);
  • fixed PIL support for CMYK files (thanks Michael Wu);
  • optional C extension is rebuilt with Cython 0.23.4;
  • Python 3.2 support is dropped; the package still works in Python 3.2, but the compatibility is no longer checked by tests, and so it can break in future.
  • declare Python 3.5 as supported.

1.2 (2015-01-27)

  • implemented extraction of embedded files (embedded smart objects) - thanks Volker Braun;
  • optional C extension is rebuilt with Cython 0.21.2.
  • hg mirror on bitbucket is dropped, sorry!

1.1 (2014-11-17)

  • improved METADATA_SETTING decoding (thanks Evgeny Kopylov);
  • layer comps decoding (thanks Evgeny Kopylov);
  • improved smart objects decoding (thanks Joey Gentry);
  • user API for getting layer transforms and placed layer size (thanks Joey Gentry);
  • IPython import is deferred to speedup psd-tools.py command-line utility;
  • _RootGroup.__repr__ is fixed;
  • warning message building is more robust;
  • optional C extension is rebuilt with Cython 0.21.1.

1.0 (2014-07-24)

  • Fixed reading of images with layer masks (thanks Evgeny Kopylov);
  • improved mask data decoding (thanks Evgeny Kopylov);
  • fixed synchronization in case of 8B64 signatures (thanks Evgeny Kopylov);
  • fixed reading of layers with zero length (thanks Evgeny Kopylov);
  • fixed Descriptor parsing (thanks Evgeny Kopylov);
  • some of the descriptor structures and tagged block constants are renamed (thanks Evgeny Kopylov);
  • PATH_SELECTION_STATE decoding (thanks Evgeny Kopylov);
  • the library is switched to setuptools; docopt is now installed automatically.

0.10 (2014-06-15)

  • Layer effects parsing (thanks Evgeny Kopylov);
  • trailing null bytes are stripped from descriptor strings (thanks Evgeny Kopylov);
  • "Reference" and "List" descriptor parsing is fixed (thanks Evgeny Kopylov);
  • scalar descriptor values (doubles, floats, booleans) are now returned as scalars, not as lists of size 1 (thanks Evgeny Kopylov);
  • fixed reading of EngineData past declared length (thanks Carlton P. Taylor);
  • "background color" Image Resource parsing (thanks Evgeny Kopylov);
  • psd_tools.decoder.actions.Enum.enum field is renamed to psd_tools.decoder.actions.Enum.value (thanks Evgeny Kopylov);
  • code simplification - constants are now bytestrings as they should be (thanks Evgeny Kopylov);
  • Python 3.4 is supported.

0.9.1 (2014-03-26)

  • Improved merging of transparent layers (thanks Vladimir Timofeev);
  • fixed layer merging and bounding box calculations for empty layers (thanks Vladimir Timofeev);
  • C extension is rebuilt with Cython 0.20.1.

0.9 (2013-12-03)

  • psd-tools.py command-line interface is changed, 'debug' command is added;
  • pretty-printing of internal structures;
  • pymaging support is fixed;
  • allow 'MeSa' to be a signature for image resource blocks (thanks Alexey Buzanov);
  • psd_tools.debug.debug_view utility function is fixed;
  • Photoshop CC constants are added;
  • Photoshop CC vector origination data is decoded;
  • binary data is preserved if descriptor parsing fails;
  • more verbose logging for PSD reader;
  • channel data reader became more robust - now it doesn't read past declared channel length;
  • psd-tools.py --version command is fixed;
  • lsdk tagged blocks parsing: this fixes some issues with layer grouping (thanks Ivan Maradzhyiski for the bug report and the patch);
  • CMYK images support is added (thanks Alexey Buzanov, Guillermo Rauch and <https://github.com/a-e-m> for the help);
  • Grayscale images support is added (thanks <https://github.com/a-e-m>);
  • LittleCMS is now optional (but it is still required to get proper colors).

0.8.4 (2013-06-12)

Point and Millimeter types are added to UnitFloatType (thanks Doug Ellwanger).

0.8.3 (2013-06-01)

Some issues with descriptor parsing are fixed (thanks Luke Petre).

0.8.2 (2013-04-12)

Python 2.x: reading data from file-like objects is fixed (thanks Pavel Zinovkin).

0.8.1 (2013-03-02)

  • Fixed parsing of layer groups without explicit OPEN_FOLDER mark;
  • Cython extension is rebuilt with Cython 0.18.

0.8 (2013-02-26)

  • Descriptor parsing (thanks Oliver Zheng);
  • text (as string) is extracted from text layers (thanks Oliver Zheng);
  • improved support for optional building of Cython extension.

0.7.1 (2012-12-27)

Typo is fixed: LayerRecord.cilpping should be LayerRecord.clipping. Thanks Oliver Zheng.

0.7 (2012-11-08)

  • Highly experimental: basic layer merging is implemented (e.g. it is now possible to export layer group to a PIL image);
  • Layer.visible no longer takes group visibility in account;
  • Layer.visible_global is the old Layer.visible;
  • psd_tools.user_api.combined_bbox made public;
  • Layer.width and Layer.height are removed (use layer.bbox.width and layer.bbox.height instead);
  • pil_support.composite_image_to_PIL is renamed to pil_support.extract_composite_image and pil_support.layer_to_PIL is renamed to pil_support.extract_layer_image in order to have the same API for pil_support and pymaging_support.

0.6 (2012-11-06)

  • psd.composite_image() is renamed to psd.as_PIL();
  • Pymaging support: psd.as_pymaging() and layer.as_pymaging() methods.

0.5 (2012-11-05)

  • Support for zip and zip-with-prediction compression methods is added;
  • support for 16/32bit layers is added;
  • optional Cython extension for faster zip-with-prediction decompression;
  • other speed improvements.

0.2 (2012-11-04)

  • Initial support for 16bit and 32bit PSD files: psd-tools v0.2 can read composite (merged) images for such files and extract information (names, dimensions, hierarchy, etc.) about layers and groups of 16/32bit PSD; extracting image data for distinct layers in 16/32bit PSD files is not suported yet;
  • better Layer.__repr__;
  • bbox property for Group.

0.1.4 (2012-11-01)

Packaging is fixed in this release.

0.1.3 (2012-11-01)

  • Better support for 32bit images (still incomplete);
  • reader is able to handle "global" tagged layer info blocks that was previously discarded.

0.1.2 (2012-10-30)

  • warn about 32bit images;
  • transparency support for composite images.

0.1.1 (2012-10-29)

Initial release (v0.1 had packaging issues).

Contributing

Development happens at github: bug tracker <https://github.com/psd-tools/psd-tools/issues>. Feel free to submit bug reports <https://github.com/psd-tools/psd-tools/issues/new> or pull requests. Attaching an erroneous PSD file makes the debugging process faster. Such PSD file might be added to the test suite.

The license is MIT.

Package design

The package consists of four major subpackages:

1.
psd_tools.psd <#module-psd_tools.psd>: subpackage that reads/writes low-level binary
structure of the PSD/PSB file. The core data structures are built around attrs <https://www.attrs.org/en/stable/index.html#> classes that all implement read and write methods. Each data object tries to resemble the structure described in the specification <https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/>. Although documented, the specification <https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/> is far from complete and some are even inaccurate. When psd-tools finds unknown data structure, the package keeps such data as bytes in the parsed result.


2.
psd_tools.api <#module-psd_tools.api>: User-facing API that implements various
easy-to-use methods that manipulate low-level psd_tools.psd <#module-psd_tools.psd> data structures. This is the primary interface for most users.

3.
psd_tools.composite <#module-psd_tools.composite>: Rendering engine for layer compositing and
blending. This subpackage implements blend modes, layer effects (drop shadows, strokes, etc.), and vector shape rasterization. It uses NumPy arrays for efficient pixel manipulation and includes optional dependencies (scipy, scikit-image, aggdraw) that must be installed via the composite extra.

4.
psd_tools.compression <#module-psd_tools.compression>: Image compression codecs for raw data,
RLE (Run-Length Encoding), and ZIP compression. The RLE codec includes a Cython-optimized implementation (_rle.pyx) that falls back to pure Python if not compiled, providing significant performance improvements for large files.


In the future, it might be good to implement the Photoshop API <https://developer.adobe.com/photoshop/uxp/2022/ps_reference/> on top of the existing psd-tools API.

Testing

In order to run tests, make sure PIL/Pillow is built with LittleCMS or LittleCMS2 support. For example, on Ubuntu, install the following packages:

apt-get install liblcms2-dev libjpeg-dev libfreetype6-dev zlib1g-dev


Then install psd-tools with development dependencies:

uv sync --group dev --extra composite


Finally, run tests:

uv run pytest


Documentation

Install documentation dependencies:

uv sync --group docs


Once installed, use Makefile:

make docs


Release Process

Releases are automated via GitHub Actions. To create a new release:

1.
Ensure all changes are committed and pushed to main:

git checkout main
git pull origin main


2.
Create and push a version tag:

git tag v1.x.x
git push origin v1.x.x


3.
Automated workflow:

Once the tag is pushed, the release workflow automatically:

  • Builds wheels for all supported platforms (Linux, Windows, macOS including ARM)
  • Generates release notes from git commits since the previous tag
  • Creates a GitHub release with the auto-generated changelog
  • Publishes the package to PyPI

4.
Verify the release:


Note: Only maintainers with appropriate repository permissions can push tags and trigger releases. PyPI credentials are stored as repository secrets.

Acknowledgments

Great thanks to all the contributors <https://github.com/psd-tools/psd-tools/graphs/contributors>.

FEATURES

Supported:

  • Read and write of the low-level PSD/PSB file structure
  • Raw layer image export in NumPy and PIL format

Limited support:

  • Composition of basic pixel-based layers
  • Composition of fill layer effects
  • Vector masks
  • Editing of some layer attributes such as layer name
  • Basic editing of pixel layers and groups, such as adding or removing a layer
  • Blending modes except for dissolve
  • Drawing of bezier curves

Not supported:

  • Editing of various layers such as type layers, shape layers, smart objects, etc.
  • Editing of texts in type layers
  • Composition of adjustment layers
  • Composition of many layer effects
  • Font rendering

psd_tools

See Usage <> for examples.

PSDImage

Photoshop PSD/PSB document.

The low-level data structure is accessible at PSDImage._record.

Example:

from psd_tools import PSDImage
psdimage = PSDImage.open('example.psd')
image = psdimage.composite()
for layer in psdimage:

layer_image = layer.composite()


Add a layer to the end (top) of the group.

This operation rewrites the internal references of the layer. Adding the same layer will not create a duplicate.

layer -- The layer to add.
  • TypeError -- If the provided object is not a Layer instance.
  • ValueError -- If attempting to add a group to itself.



Minimal bounding box that contains all the visible layers.

Use viewbox <#psd_tools.api.psd_image.PSDImage.viewbox> to get viewport bounding box. When the psd is empty, bbox is equal to the canvas bounding box.

(left, top, right, bottom) tuple.


Bottom coordinate.
int


Number of color channels.
int


Clears the group.

This operation rewrites the internal references of the layers.

None


Document color mode, such as 'RGB' or 'GRAYSCALE'. See ColorMode <#psd_tools.constants.ColorMode>.
ColorMode <#psd_tools.constants.ColorMode>


Set the compositing and layer organization compatibility mode. Writable.

This property checks whether the PSD file is compatible with specific authoring tools, such as Photoshop or CLIP Studio Paint. Different authoring tools may have different ways of handling layers, such as the use of clipping masks for groups. Default is Photoshop compatibility mode.

CompatibilityMode <#psd_tools.constants.CompatibilityMode>


Composite the PSD image.
  • viewport -- Viewport bounding box specified by (x1, y1, x2, y2) tuple. Default is the viewbox of the PSD.
  • ignore_preview -- Boolean flag to whether skip compositing when a pre-composited preview is available.
  • force -- Boolean flag to force vector drawing.
  • color -- Backdrop color specified by scalar or tuple of scalar. The color value should be in [0.0, 1.0]. For example, (1., 0., 0.) specifies red in RGB color mode.
  • alpha -- Backdrop alpha in [0.0, 1.0].
  • layer_filter -- Callable that takes a layer as argument and returns whether if the layer is composited. Default is is_visible().

PIL.Image.


Counts the number of occurrences of a layer in the group.
layer -- The layer to count.


Create a new group layer and add it to the PSDImage.

Example:

group = psdimage.create_group(name='New Group')
group.append(psdimage.create_pixel_layer(image, name='Layer in Group'))


  • layer_list -- Optional list of layers to add to the group.
  • name -- Name of the new group.
  • opacity -- Opacity of the new layer (0-255).
  • blend_mode -- Blend mode of the new layer, default is BlendMode.PASS_THROUGH.
  • open_folder -- Whether the group is an open folder in the Photoshop UI.

The created Group <#psd_tools.api.layers.Group> object.


Create a new pixel layer and add it to the PSDImage.

Example:

psdimage = PSDImage.new("RGB", (640, 480))
layer = psdimage.create_pixel_layer(image, name='Layer 1')


  • name -- Name of the new layer.
  • image -- PIL Image object.
  • top -- Top coordinate of the new layer.
  • left -- Left coordinate of the new layer.
  • compression -- Compression method for the layer image data.
  • opacity -- Opacity of the new layer (0-255).
  • blend_mode -- Blend mode of the new layer, default is BlendMode.NORMAL.

The created PixelLayer <#psd_tools.api.layers.PixelLayer> object.


Pixel depth bits.
int


Return a generator to iterate over all descendant layers.
include_clip -- Whether to include clipping layers. Default is True.

Example:

# Iterate over all layers
for layer in psd.descendants():

print(layer) # Iterate over all layers in reverse order for layer in reversed(list(psd.descendants())):
print(layer)



Add a list of layers to the end (top) of the group.

This operation rewrites the internal references of the layers. Adding the same layer will not create a duplicate.

layers -- The layers to add.
  • TypeError -- If the provided object is not a Layer instance.
  • ValueError -- If attempting to add a group to itself.



Returns the first layer found for the given layer name
name


Return a generator to iterate over all layers with the given name.
name


Create a new layer-less PSD document from PIL Image.
  • image -- PIL Image object.
  • compression -- ImageData compression option. See Compression <#psd_tools.constants.Compression>.

A PSDImage <#psd_tools.api.psd_image.PSDImage> object.


Returns if the document has real merged data. When True, topil() returns pre-composed data.

True if the PSDImage has a thumbnail resource.

Document height.
int


Document image resources. ImageResources <#psd_tools.psd.image_resources.ImageResources> is a dict-like structure that keeps various document settings.

See psd_tools.constants.Resource <#psd_tools.constants.Resource> for available keys.

ImageResources <#psd_tools.psd.image_resources.ImageResources>

Example:

from psd_tools.constants import Resource
version_info = psd.image_resources.get_data(Resource.VERSION_INFO)
slices = psd.image_resources.get_data(Resource.SLICES)


Image resources contain an ICC profile. The following shows how to export a PNG file with embedded ICC profile:

from psd_tools.constants import Resource
icc_profile = psd.image_resources.get_data(Resource.ICC_PROFILE)
image = psd.compose(apply_icc=False)
image.save('output.png', icc_profile=icc_profile)



Returns the index of the specified layer in the group.
layer -- The layer to find.


Insert the given layer at the specified index.

This operation rewrites the internal references of the layer.

  • index -- The index to insert the layer at.
  • layer -- The layer to insert.

  • TypeError -- If the provided object is not a Layer instance.
  • ValueError -- If attempting to add a group to itself.



Return True if this is a group.

Returns whether the layer tree has been updated.
bool


Returns visibility of the element.

Kind.
'psdimage'


Left coordinate.


Element name.
'Root'


Create a new PSD document.
  • mode -- The color mode to use for the new image.
  • size -- A tuple containing (width, height) in pixels.
  • color -- What color to use for the image. Default is black.

A PSDImage <#psd_tools.api.psd_image.PSDImage> object.


Get NumPy array of the layer.
channel -- Which channel to return, can be 'color', 'shape', 'alpha', or 'mask'. Default is 'color+alpha'.
numpy.ndarray


(left, top) tuple.
tuple


Open a PSD document.
  • fp -- filename or file-like object.
  • encoding -- charset encoding of the pascal string within the file, default 'macroman'. Some psd files need explicit encoding option.

A PSDImage <#psd_tools.api.psd_image.PSDImage> object.


Parent of this layer.

PIL mode of the document.

Removes the specified layer from the list and returns it.

This operation rewrites the internal references of the layer.

index -- The index of the layer to remove. Default is -1 (the last layer).
IndexError -- If the index is out of range.
The removed layer.


Removes the specified layer from the group.

This operation rewrites the internal references of the layer.

layer -- The layer to remove.
ValueError -- If the layer is not found in the group.
self


Right coordinate.
int


Save the PSD file. Updates the ImageData section if the layer structure has been updated.
  • fp -- filename or file-like object.
  • encoding -- charset encoding of the pascal string within the file, default 'macroman'.
  • mode -- file open mode, default 'wb'.



(width, height) tuple.
tuple


Document tagged blocks that is a dict-like container of settings.

See psd_tools.constants.Tag <#psd_tools.constants.Tag> for available keys.

TaggedBlocks <#psd_tools.psd.tagged_blocks.TaggedBlocks> or None.

Example:

from psd_tools.constants import Tag
patterns = psd.tagged_blocks.get_data(Tag.PATTERNS1)



Returns a thumbnail image in PIL.Image. When the file does not contain an embedded thumbnail image, returns None.

Top coordinate.


Get PIL Image.
  • channel -- Which channel to return; e.g., 0 for 'R' channel in RGB image. See ChannelID <#psd_tools.constants.ChannelID>. When None, the method returns all the channels supported by PIL modes.
  • apply_icc -- Whether to apply ICC profile conversion to sRGB.

PIL.Image, or None if the composed image is not available.


Document version. PSD file is 1, and PSB file is 2.
int


Return bounding box of the viewport.
(left, top, right, bottom) tuple.


Visibility.
True


Document width.
int



psd_tools.api

High-level API for working with PSD/PSB files.

This subpackage provides the user-facing API for psd-tools, offering Pythonic interfaces for manipulating Photoshop documents. It wraps the low-level psd_tools.psd <#module-psd_tools.psd> binary structures with convenient methods and properties.

The main entry point is PSDImage, which provides document-level operations. Individual layers are represented by various layer classes in psd_tools.api.layers <#module-psd_tools.api.layers>.

Key modules:

  • psd_tools.api.psd_image: Main PSDImage class for document operations
  • psd_tools.api.layers <#module-psd_tools.api.layers>: Layer type hierarchy (Layer, GroupMixin, etc.)
  • psd_tools.api.adjustments <#module-psd_tools.api.adjustments>: Adjustment layer types
  • psd_tools.api.mask <#module-psd_tools.api.mask>: Layer mask operations
  • psd_tools.api.shape <#module-psd_tools.api.shape>: Vector shape and stroke operations
  • psd_tools.api.effects <#module-psd_tools.api.effects>: Layer effects (shadows, glows, etc.)
  • psd_tools.api.pil_io: PIL/Pillow image I/O utilities
  • psd_tools.api.numpy_io: NumPy array I/O utilities

Example usage:

from psd_tools import PSDImage
# Open a PSD file
psd = PSDImage.open('document.psd')
# Access layers
for layer in psd:

print(f"{layer.name}: {layer.kind}") # Modify a layer layer = psd[0] layer.name = "New Name" layer.opacity = 128 # Save changes psd.save('modified.psd')


The API layer automatically reconstructs the layer tree from the flat list of layer records in the PSD file, establishing proper parent-child relationships for groups.

This module provides the high-level API for working with PSD files. It wraps the low-level psd_tools.psd <#module-psd_tools.psd> structures with convenient Pythonic interfaces.

PSDImage

Photoshop PSD/PSB document.

The low-level data structure is accessible at PSDImage._record.

Example:

from psd_tools import PSDImage
psdimage = PSDImage.open('example.psd')
image = psdimage.composite()
for layer in psdimage:

layer_image = layer.composite()


Add a layer to the end (top) of the group.

This operation rewrites the internal references of the layer. Adding the same layer will not create a duplicate.

layer -- The layer to add.
  • TypeError -- If the provided object is not a Layer instance.
  • ValueError -- If attempting to add a group to itself.



Minimal bounding box that contains all the visible layers.

Use viewbox to get viewport bounding box. When the psd is empty, bbox is equal to the canvas bounding box.

(left, top, right, bottom) tuple.


Bottom coordinate.
int


Number of color channels.
int


Clears the group.

This operation rewrites the internal references of the layers.

None


Document color mode, such as 'RGB' or 'GRAYSCALE'. See ColorMode <#psd_tools.constants.ColorMode>.
ColorMode <#psd_tools.constants.ColorMode>


Set the compositing and layer organization compatibility mode. Writable.

This property checks whether the PSD file is compatible with specific authoring tools, such as Photoshop or CLIP Studio Paint. Different authoring tools may have different ways of handling layers, such as the use of clipping masks for groups. Default is Photoshop compatibility mode.

CompatibilityMode <#psd_tools.constants.CompatibilityMode>


Composite the PSD image.
  • viewport -- Viewport bounding box specified by (x1, y1, x2, y2) tuple. Default is the viewbox of the PSD.
  • ignore_preview -- Boolean flag to whether skip compositing when a pre-composited preview is available.
  • force -- Boolean flag to force vector drawing.
  • color -- Backdrop color specified by scalar or tuple of scalar. The color value should be in [0.0, 1.0]. For example, (1., 0., 0.) specifies red in RGB color mode.
  • alpha -- Backdrop alpha in [0.0, 1.0].
  • layer_filter -- Callable that takes a layer as argument and returns whether if the layer is composited. Default is is_visible().

PIL.Image.


Counts the number of occurrences of a layer in the group.
layer -- The layer to count.


Create a new group layer and add it to the PSDImage.

Example:

group = psdimage.create_group(name='New Group')
group.append(psdimage.create_pixel_layer(image, name='Layer in Group'))


  • layer_list -- Optional list of layers to add to the group.
  • name -- Name of the new group.
  • opacity -- Opacity of the new layer (0-255).
  • blend_mode -- Blend mode of the new layer, default is BlendMode.PASS_THROUGH.
  • open_folder -- Whether the group is an open folder in the Photoshop UI.

The created Group <#psd_tools.api.layers.Group> object.


Create a new pixel layer and add it to the PSDImage.

Example:

psdimage = PSDImage.new("RGB", (640, 480))
layer = psdimage.create_pixel_layer(image, name='Layer 1')


  • name -- Name of the new layer.
  • image -- PIL Image object.
  • top -- Top coordinate of the new layer.
  • left -- Left coordinate of the new layer.
  • compression -- Compression method for the layer image data.
  • opacity -- Opacity of the new layer (0-255).
  • blend_mode -- Blend mode of the new layer, default is BlendMode.NORMAL.

The created PixelLayer <#psd_tools.api.layers.PixelLayer> object.


Pixel depth bits.
int


Return a generator to iterate over all descendant layers.
include_clip -- Whether to include clipping layers. Default is True.

Example:

# Iterate over all layers
for layer in psd.descendants():

print(layer) # Iterate over all layers in reverse order for layer in reversed(list(psd.descendants())):
print(layer)



Add a list of layers to the end (top) of the group.

This operation rewrites the internal references of the layers. Adding the same layer will not create a duplicate.

layers -- The layers to add.
  • TypeError -- If the provided object is not a Layer instance.
  • ValueError -- If attempting to add a group to itself.



Returns the first layer found for the given layer name
name


Return a generator to iterate over all layers with the given name.
name


Create a new layer-less PSD document from PIL Image.
  • image -- PIL Image object.
  • compression -- ImageData compression option. See Compression <#psd_tools.constants.Compression>.

A PSDImage object.


Returns if the document has real merged data. When True, topil() returns pre-composed data.

True if the PSDImage has a thumbnail resource.

Document height.
int


Document image resources. ImageResources <#psd_tools.psd.image_resources.ImageResources> is a dict-like structure that keeps various document settings.

See psd_tools.constants.Resource <#psd_tools.constants.Resource> for available keys.

ImageResources <#psd_tools.psd.image_resources.ImageResources>

Example:

from psd_tools.constants import Resource
version_info = psd.image_resources.get_data(Resource.VERSION_INFO)
slices = psd.image_resources.get_data(Resource.SLICES)


Image resources contain an ICC profile. The following shows how to export a PNG file with embedded ICC profile:

from psd_tools.constants import Resource
icc_profile = psd.image_resources.get_data(Resource.ICC_PROFILE)
image = psd.compose(apply_icc=False)
image.save('output.png', icc_profile=icc_profile)



Returns the index of the specified layer in the group.
layer -- The layer to find.


Insert the given layer at the specified index.

This operation rewrites the internal references of the layer.

  • index -- The index to insert the layer at.
  • layer -- The layer to insert.

  • TypeError -- If the provided object is not a Layer instance.
  • ValueError -- If attempting to add a group to itself.



Return True if this is a group.

Returns whether the layer tree has been updated.
bool


Returns visibility of the element.

Kind.
'psdimage'


Left coordinate.


Element name.
'Root'


Create a new PSD document.
  • mode -- The color mode to use for the new image.
  • size -- A tuple containing (width, height) in pixels.
  • color -- What color to use for the image. Default is black.

A PSDImage object.


Get NumPy array of the layer.
channel -- Which channel to return, can be 'color', 'shape', 'alpha', or 'mask'. Default is 'color+alpha'.
numpy.ndarray


(left, top) tuple.
tuple


Open a PSD document.
  • fp -- filename or file-like object.
  • encoding -- charset encoding of the pascal string within the file, default 'macroman'. Some psd files need explicit encoding option.

A PSDImage object.


Parent of this layer.

PIL mode of the document.

Removes the specified layer from the list and returns it.

This operation rewrites the internal references of the layer.

index -- The index of the layer to remove. Default is -1 (the last layer).
IndexError -- If the index is out of range.
The removed layer.


Removes the specified layer from the group.

This operation rewrites the internal references of the layer.

layer -- The layer to remove.
ValueError -- If the layer is not found in the group.
self


Right coordinate.
int


Save the PSD file. Updates the ImageData section if the layer structure has been updated.
  • fp -- filename or file-like object.
  • encoding -- charset encoding of the pascal string within the file, default 'macroman'.
  • mode -- file open mode, default 'wb'.



(width, height) tuple.
tuple


Document tagged blocks that is a dict-like container of settings.

See psd_tools.constants.Tag <#psd_tools.constants.Tag> for available keys.

TaggedBlocks <#psd_tools.psd.tagged_blocks.TaggedBlocks> or None.

Example:

from psd_tools.constants import Tag
patterns = psd.tagged_blocks.get_data(Tag.PATTERNS1)



Returns a thumbnail image in PIL.Image. When the file does not contain an embedded thumbnail image, returns None.

Top coordinate.


Get PIL Image.
  • channel -- Which channel to return; e.g., 0 for 'R' channel in RGB image. See ChannelID <#psd_tools.constants.ChannelID>. When None, the method returns all the channels supported by PIL modes.
  • apply_icc -- Whether to apply ICC profile conversion to sRGB.

PIL.Image, or None if the composed image is not available.


Document version. PSD file is 1, and PSB file is 2.
int


Return bounding box of the viewport.
(left, top, right, bottom) tuple.


Visibility.
True


Document width.
int



For detailed layer types documentation, see psd_tools.api.layers <>.

psd_tools.api.adjustments

Adjustment and fill layers.

Example:

if layer.kind == 'brightnesscontrast':

print(layer.brightness) if layer.kind == 'gradientfill':
print(layer.gradient_kind)


Fill layers

Fill layers are similar to ShapeLayer <#psd_tools.api.layers.ShapeLayer> except that the layer might not have an associated vector mask. The layer therefore expands the entire canvas of the PSD document.

Fill layers all inherit from FillLayer.

Example:

if isinstance(layer, psd_tools.layers.FillLayer):

image = layer.compose()


SolidColorFill

Solid color fill.
(left, top, right, bottom) tuple.

Blend mode of this layer. Writable.

Example:

from psd_tools.constants import BlendMode
if layer.blend_mode == BlendMode.NORMAL:

layer.blend_mode = BlendMode.SCREEN


BlendMode <#psd_tools.constants.BlendMode>.


Bottom coordinate.
int


Clip layers associated with this layer.
list of layers


Clipping flag for this layer. Writable.
bool


Deprecated. Use clipping property instead.

Composite layer and masks (mask, vector mask, and clipping layers).
  • viewport -- Viewport bounding box specified by (x1, y1, x2, y2) tuple. Default is the layer's bbox.
  • force -- Boolean flag to force vector drawing.
  • color -- Backdrop color specified by scalar or tuple of scalar. The color value should be in [0.0, 1.0]. For example, (1., 0., 0.) specifies red in RGB color mode.
  • alpha -- Backdrop alpha in [0.0, 1.0].
  • layer_filter -- Callable that takes a layer as argument and returns whether if the layer is composited. Default is is_visible().

PIL.Image.Image or None.


Color in Descriptor(RGB).

Deprecated: Use layer.parent.remove(layer) instead.

Layer effects.
Effects <#psd_tools.api.effects.Effects>


Fill opacity of this layer in [0, 255] range. Writable.
int


Returns True if the layer has associated clipping.
visible -- If True, check for visible clipping layers.
bool


Returns True if the layer has effects.
  • enabled -- If True, check for enabled effects.
  • name -- If given, check for specific effect type.

bool


Returns True if the layer has a mask.
bool


Returns True if the layer has live shape properties.
bool


Returns True if the layer has associated pixels. When this is True, topil method returns PIL.Image.Image.
bool


Returns True if the shape has a stroke.

Returns True if the layer has a vector mask.
bool


Height of the layer.
int


Return True if the layer is a group.
bool


Layer visibility. Takes group visibility in account.
bool


Kind of this layer, such as group, pixel, shape, type, smartobject, or psdimage. Class name without layer suffix.
str


Layer ID.
int layer id. if the layer is not assigned an id, -1.


Left coordinate. Writable.
int


Locks a layer accordind to the combination of flags.
lockflags -- An integer representing the locking state

Example using the constants of ProtectedFlags and bitwise or operation to lock both pixels and positions:

layer.lock(ProtectedFlags.COMPOSITE | ProtectedFlags.POSITION)



Returns mask associated with this layer.
Mask <#psd_tools.api.mask.Mask> or None


Moves the layer down a certain offset within the group the layer is in.
offset -- The number of positions to move the layer down (can be negative).
  • ValueError -- If layer has no parent or parent is not a group
  • IndexError -- If the new index is out of bounds

self


Deprecated: Use group.append(layer) instead.
group -- The group the current layer will be moved into.


Moves the layer up a certain offset within the group the layer is in.
offset -- The number of positions to move the layer up (can be negative).
  • ValueError -- If layer has no parent or parent is not a group
  • IndexError -- If the new index is out of bounds

self


Layer name. Writable.
str



Get NumPy array of the layer.
channel -- Which channel to return, can be 'color', 'shape', 'alpha', or 'mask'. Default is 'color+alpha'.
numpy.ndarray or None if there is no pixel.


(left, top) tuple. Writable.
tuple


Opacity of this layer in [0, 255] range. Writable.
int


Property for a list of live shapes or a line.

Some of the vector masks have associated live shape properties, that are Photoshop feature to handle primitive shapes such as a rectangle, an ellipse, or a line. Vector masks without live shape properties are plain path objects.

See psd_tools.api.shape <#module-psd_tools.api.shape>.

List of Invalidated <#psd_tools.api.shape.Invalidated>, Rectangle <#psd_tools.api.shape.Rectangle>, RoundedRectangle <#psd_tools.api.shape.RoundedRectangle>, Ellipse <#psd_tools.api.shape.Ellipse>, or Line <#psd_tools.api.shape.Line>.




Reference point of this layer as (x, y) tuple in the canvas coordinates. Writable.

Reference point is used for transformations such as rotation and scaling.

(x, y) tuple


Right coordinate.
int


(width, height) tuple.
tuple



Layer tagged blocks that is a dict-like container of settings.

See psd_tools.constants.Tag <#psd_tools.constants.Tag> for available keys.

TaggedBlocks <#psd_tools.psd.tagged_blocks.TaggedBlocks>.

Example:

from psd_tools.constants import Tag
metadata = layer.tagged_blocks.get_data(Tag.METADATA_SETTING)



Top coordinate. Writable.
int


Get PIL Image of the layer.
  • channel -- Which channel to return; e.g., 0 for 'R' channel in RGB image. See ChannelID <#psd_tools.constants.ChannelID>. When None, the method returns all the channels supported by PIL modes.
  • apply_icc -- Whether to apply ICC profile conversion to sRGB.

PIL.Image.Image, or None if the layer has no pixels.

Example:

from psd_tools.constants import ChannelID
image = layer.topil()
red = layer.topil(ChannelID.CHANNEL_0)
alpha = layer.topil(ChannelID.TRANSPARENCY_MASK)


Note:

Not all of the PSD image modes are supported in PIL.Image.Image. For example, 'CMYK' mode cannot include alpha channel in PIL. In this case, topil drops alpha channel.



Returns vector mask associated with this layer.
VectorMask <#psd_tools.api.shape.VectorMask> or None


Layer visibility. Doesn't take group visibility in account. Writable.
bool


Width of the layer.
int



PatternFill

Pattern fill.
(left, top, right, bottom) tuple.

Blend mode of this layer. Writable.

Example:

from psd_tools.constants import BlendMode
if layer.blend_mode == BlendMode.NORMAL:

layer.blend_mode = BlendMode.SCREEN


BlendMode <#psd_tools.constants.BlendMode>.


Bottom coordinate.
int


Clip layers associated with this layer.
list of layers


Clipping flag for this layer. Writable.
bool


Deprecated. Use clipping property instead.

Composite layer and masks (mask, vector mask, and clipping layers).
  • viewport -- Viewport bounding box specified by (x1, y1, x2, y2) tuple. Default is the layer's bbox.
  • force -- Boolean flag to force vector drawing.
  • color -- Backdrop color specified by scalar or tuple of scalar. The color value should be in [0.0, 1.0]. For example, (1., 0., 0.) specifies red in RGB color mode.
  • alpha -- Backdrop alpha in [0.0, 1.0].
  • layer_filter -- Callable that takes a layer as argument and returns whether if the layer is composited. Default is is_visible().

PIL.Image.Image or None.


Pattern in Descriptor(PATTERN).

Deprecated: Use layer.parent.remove(layer) instead.

Layer effects.
Effects <#psd_tools.api.effects.Effects>


Fill opacity of this layer in [0, 255] range. Writable.
int


Returns True if the layer has associated clipping.
visible -- If True, check for visible clipping layers.
bool


Returns True if the layer has effects.
  • enabled -- If True, check for enabled effects.
  • name -- If given, check for specific effect type.

bool


Returns True if the layer has a mask.
bool


Returns True if the layer has live shape properties.
bool


Returns True if the layer has associated pixels. When this is True, topil method returns PIL.Image.Image.
bool


Returns True if the shape has a stroke.

Returns True if the layer has a vector mask.
bool


Height of the layer.
int


Return True if the layer is a group.
bool


Layer visibility. Takes group visibility in account.
bool


Kind of this layer, such as group, pixel, shape, type, smartobject, or psdimage. Class name without layer suffix.
str


Layer ID.
int layer id. if the layer is not assigned an id, -1.


Left coordinate. Writable.
int


Locks a layer accordind to the combination of flags.
lockflags -- An integer representing the locking state

Example using the constants of ProtectedFlags and bitwise or operation to lock both pixels and positions:

layer.lock(ProtectedFlags.COMPOSITE | ProtectedFlags.POSITION)



Returns mask associated with this layer.
Mask <#psd_tools.api.mask.Mask> or None


Moves the layer down a certain offset within the group the layer is in.
offset -- The number of positions to move the layer down (can be negative).
  • ValueError -- If layer has no parent or parent is not a group
  • IndexError -- If the new index is out of bounds

self


Deprecated: Use group.append(layer) instead.
group -- The group the current layer will be moved into.


Moves the layer up a certain offset within the group the layer is in.
offset -- The number of positions to move the layer up (can be negative).
  • ValueError -- If layer has no parent or parent is not a group
  • IndexError -- If the new index is out of bounds

self


Layer name. Writable.
str



Get NumPy array of the layer.
channel -- Which channel to return, can be 'color', 'shape', 'alpha', or 'mask'. Default is 'color+alpha'.
numpy.ndarray or None if there is no pixel.


(left, top) tuple. Writable.
tuple


Opacity of this layer in [0, 255] range. Writable.
int


Property for a list of live shapes or a line.

Some of the vector masks have associated live shape properties, that are Photoshop feature to handle primitive shapes such as a rectangle, an ellipse, or a line. Vector masks without live shape properties are plain path objects.

See psd_tools.api.shape <#module-psd_tools.api.shape>.

List of Invalidated <#psd_tools.api.shape.Invalidated>, Rectangle <#psd_tools.api.shape.Rectangle>, RoundedRectangle <#psd_tools.api.shape.RoundedRectangle>, Ellipse <#psd_tools.api.shape.Ellipse>, or Line <#psd_tools.api.shape.Line>.




Reference point of this layer as (x, y) tuple in the canvas coordinates. Writable.

Reference point is used for transformations such as rotation and scaling.

(x, y) tuple


Right coordinate.
int


(width, height) tuple.
tuple



Layer tagged blocks that is a dict-like container of settings.

See psd_tools.constants.Tag <#psd_tools.constants.Tag> for available keys.

TaggedBlocks <#psd_tools.psd.tagged_blocks.TaggedBlocks>.

Example:

from psd_tools.constants import Tag
metadata = layer.tagged_blocks.get_data(Tag.METADATA_SETTING)



Top coordinate. Writable.
int


Get PIL Image of the layer.
  • channel -- Which channel to return; e.g., 0 for 'R' channel in RGB image. See ChannelID <#psd_tools.constants.ChannelID>. When None, the method returns all the channels supported by PIL modes.
  • apply_icc -- Whether to apply ICC profile conversion to sRGB.

PIL.Image.Image, or None if the layer has no pixels.

Example:

from psd_tools.constants import ChannelID
image = layer.topil()
red = layer.topil(ChannelID.CHANNEL_0)
alpha = layer.topil(ChannelID.TRANSPARENCY_MASK)


Note:

Not all of the PSD image modes are supported in PIL.Image.Image. For example, 'CMYK' mode cannot include alpha channel in PIL. In this case, topil drops alpha channel.



Returns vector mask associated with this layer.
VectorMask <#psd_tools.api.shape.VectorMask> or None


Layer visibility. Doesn't take group visibility in account. Writable.
bool


Width of the layer.
int



GradientFill

Gradient fill.
(left, top, right, bottom) tuple.

Blend mode of this layer. Writable.

Example:

from psd_tools.constants import BlendMode
if layer.blend_mode == BlendMode.NORMAL:

layer.blend_mode = BlendMode.SCREEN


BlendMode <#psd_tools.constants.BlendMode>.


Bottom coordinate.
int


Clip layers associated with this layer.
list of layers


Clipping flag for this layer. Writable.
bool


Deprecated. Use clipping property instead.

Composite layer and masks (mask, vector mask, and clipping layers).
  • viewport -- Viewport bounding box specified by (x1, y1, x2, y2) tuple. Default is the layer's bbox.
  • force -- Boolean flag to force vector drawing.
  • color -- Backdrop color specified by scalar or tuple of scalar. The color value should be in [0.0, 1.0]. For example, (1., 0., 0.) specifies red in RGB color mode.
  • alpha -- Backdrop alpha in [0.0, 1.0].
  • layer_filter -- Callable that takes a layer as argument and returns whether if the layer is composited. Default is is_visible().

PIL.Image.Image or None.


Gradient in Descriptor(GRADIENT).

Deprecated: Use layer.parent.remove(layer) instead.

Layer effects.
Effects <#psd_tools.api.effects.Effects>


Fill opacity of this layer in [0, 255] range. Writable.
int


Kind of the gradient, one of the following:
  • Linear
  • Radial
  • Angle
  • Reflected
  • Diamond




Returns True if the layer has associated clipping.
visible -- If True, check for visible clipping layers.
bool


Returns True if the layer has effects.
  • enabled -- If True, check for enabled effects.
  • name -- If given, check for specific effect type.

bool


Returns True if the layer has a mask.
bool


Returns True if the layer has live shape properties.
bool


Returns True if the layer has associated pixels. When this is True, topil method returns PIL.Image.Image.
bool


Returns True if the shape has a stroke.

Returns True if the layer has a vector mask.
bool


Height of the layer.
int


Return True if the layer is a group.
bool


Layer visibility. Takes group visibility in account.
bool


Kind of this layer, such as group, pixel, shape, type, smartobject, or psdimage. Class name without layer suffix.
str


Layer ID.
int layer id. if the layer is not assigned an id, -1.


Left coordinate. Writable.
int


Locks a layer accordind to the combination of flags.
lockflags -- An integer representing the locking state

Example using the constants of ProtectedFlags and bitwise or operation to lock both pixels and positions:

layer.lock(ProtectedFlags.COMPOSITE | ProtectedFlags.POSITION)



Returns mask associated with this layer.
Mask <#psd_tools.api.mask.Mask> or None


Moves the layer down a certain offset within the group the layer is in.
offset -- The number of positions to move the layer down (can be negative).
  • ValueError -- If layer has no parent or parent is not a group
  • IndexError -- If the new index is out of bounds

self


Deprecated: Use group.append(layer) instead.
group -- The group the current layer will be moved into.


Moves the layer up a certain offset within the group the layer is in.
offset -- The number of positions to move the layer up (can be negative).
  • ValueError -- If layer has no parent or parent is not a group
  • IndexError -- If the new index is out of bounds

self


Layer name. Writable.
str



Get NumPy array of the layer.
channel -- Which channel to return, can be 'color', 'shape', 'alpha', or 'mask'. Default is 'color+alpha'.
numpy.ndarray or None if there is no pixel.


(left, top) tuple. Writable.
tuple


Opacity of this layer in [0, 255] range. Writable.
int


Property for a list of live shapes or a line.

Some of the vector masks have associated live shape properties, that are Photoshop feature to handle primitive shapes such as a rectangle, an ellipse, or a line. Vector masks without live shape properties are plain path objects.

See psd_tools.api.shape <#module-psd_tools.api.shape>.

List of Invalidated <#psd_tools.api.shape.Invalidated>, Rectangle <#psd_tools.api.shape.Rectangle>, RoundedRectangle <#psd_tools.api.shape.RoundedRectangle>, Ellipse <#psd_tools.api.shape.Ellipse>, or Line <#psd_tools.api.shape.Line>.




Reference point of this layer as (x, y) tuple in the canvas coordinates. Writable.

Reference point is used for transformations such as rotation and scaling.

(x, y) tuple


Right coordinate.
int


(width, height) tuple.
tuple



Layer tagged blocks that is a dict-like container of settings.

See psd_tools.constants.Tag <#psd_tools.constants.Tag> for available keys.

TaggedBlocks <#psd_tools.psd.tagged_blocks.TaggedBlocks>.

Example:

from psd_tools.constants import Tag
metadata = layer.tagged_blocks.get_data(Tag.METADATA_SETTING)



Top coordinate. Writable.
int


Get PIL Image of the layer.
  • channel -- Which channel to return; e.g., 0 for 'R' channel in RGB image. See ChannelID <#psd_tools.constants.ChannelID>. When None, the method returns all the channels supported by PIL modes.
  • apply_icc -- Whether to apply ICC profile conversion to sRGB.

PIL.Image.Image, or None if the layer has no pixels.

Example:

from psd_tools.constants import ChannelID
image = layer.topil()
red = layer.topil(ChannelID.CHANNEL_0)
alpha = layer.topil(ChannelID.TRANSPARENCY_MASK)


Note:

Not all of the PSD image modes are supported in PIL.Image.Image. For example, 'CMYK' mode cannot include alpha channel in PIL. In this case, topil drops alpha channel.



Returns vector mask associated with this layer.
VectorMask <#psd_tools.api.shape.VectorMask> or None


Layer visibility. Doesn't take group visibility in account. Writable.
bool


Width of the layer.
int



Adjustment layers

Adjustment layers apply image filtering to the composed result. All adjustment layers inherit from AdjustmentLayer. Adjustment layers do not have pixels, and currently ignored in compose. Attempts to call topil on adjustment layers always return None.

Just as any other layer, adjustment layers might have an associated mask or vector mask. Adjustment can appear in other layers' clipping layers.

Example:

if isinstance(layer, psd_tools.layers.AdjustmentLayer):

print(layer.kind)


BrightnessContrast


Curves


Exposure


Levels

Levels adjustment.

Levels contain a list of LevelRecord.

List of level records. The first record is the master.
Levels.




Vibrance


HueSaturation

Hue/Saturation adjustment.

HueSaturation contains a list of data.


List of Hue/Saturation records.
list


Enable colorization.
int


Master record.
tuple



ColorBalance


BlackAndWhite


PhotoFilter


ChannelMixer


ColorLookup


Posterize


Threshold


SelectiveColor


GradientMap


psd_tools.api.effects

Effects module.

List-like effects.

Only present effects are kept.

Whether if all the effects are enabled.


Iterate effect items by name.
  • name -- Effect name, e.g. DropShadow, InnerShadow, OuterGlow, InnerGlow, ColorOverlay, GradientOverlay, PatternOverlay, Stroke, BevelEmboss, or Satin.
  • enabled -- If true, only return enabled effects.

Iterator[Effect]


Scale value.


DropShadow


InnerShadow


OuterGlow

Angle value.


Effect blending mode.

Choke level in pixels.




Whether if the effect is enabled.



Effect name.

Noise level in percent.


Layer effect opacity in percentage.

Whether if the effect is present in Photoshop UI.

Quality jitter in percent.

Quality range in percent.

Reverse flag.

Whether if the effect is shown in dialog.

Size in pixels.

Spread level in percent.

Gradient type, one of linear, radial, angle, reflected, or diamond.

Deprecated

Effect descriptor value. Use descriptor property instead.



InnerGlow

Angle value.


Effect blending mode.

Choke level in pixels.




Whether if the effect is enabled.

Elements source.



Effect name.

Noise level in percent.


Layer effect opacity in percentage.

Whether if the effect is present in Photoshop UI.

Quality jitter in percent.

Quality range in percent.

Reverse flag.

Whether if the effect is shown in dialog.

Size in pixels.

Gradient type, one of linear, radial, angle, reflected, or diamond.

Deprecated

Effect descriptor value. Use descriptor property instead.



ColorOverlay


GradientOverlay


Angle value.

Effect blending mode.


Whether if the effect is enabled.


Effect name.


Layer effect opacity in percentage.

Whether if the effect is present in Photoshop UI.

Reverse flag.

Scale value.

Whether if the effect is shown in dialog.

Gradient type, one of linear, radial, angle, reflected, or diamond.

Deprecated

Effect descriptor value. Use descriptor property instead.



PatternOverlay


Stroke

Angle value.

Effect blending mode.



Whether if the effect is enabled.

Fill type, SolidColor, Gradient, or Pattern.



Effect name.


Layer effect opacity in percentage.

Overprint flag.



Position of the stroke, InsetFrame, OutsetFrame, or CenteredFrame.

Whether if the effect is present in Photoshop UI.

Reverse flag.

Whether if the effect is shown in dialog.

Size value.

Gradient type, one of linear, radial, angle, reflected, or diamond.

Deprecated

Effect descriptor value. Use descriptor property instead.



BevelEmboss

Altitude value in angle.

Angle value.


Bevel style, one of OuterBevel, InnerBevel, Emboss, PillowEmboss, or StrokeEmboss.

Bevel type, one of SoftMatte, HardLight, SoftLight.


Depth value in percentage.

Direction, either StampIn or StampOut.

Whether if the effect is enabled.


Highlight blending mode.

Highlight opacity value in percentage.

Effect name.

Layer effect opacity in percentage.

Whether if the effect is present in Photoshop UI.


Shadow blending mode.

Shadow opacity value in percentage.

Whether if the effect is shown in dialog.

Size value in pixel.

Soften value in pixels.

Using global light.



Deprecated

Effect descriptor value. Use descriptor property instead.



Satin

Satin effect
Angle value in degrees.


Effect blending mode.



Distance value in pixels.

Whether if the effect is enabled.


Effect name.

Layer effect opacity in percentage.

Whether if the effect is present in Photoshop UI.

Whether if the effect is shown in dialog.

Size value in pixel.

Deprecated

Effect descriptor value. Use descriptor property instead.



psd_tools.api.layers

Layer module.

This module implements the high-level layer API for psd-tools, providing Pythonic interfaces for working with Photoshop layers. It defines the layer type hierarchy and common operations.

Key classes:

  • Layer: Base class for all layer types
  • GroupMixin: Mixin for layers that contain children (groups, documents)
  • Group: Folder/group layer containing other layers
  • PixelLayer: Regular raster layer with pixel data
  • TypeLayer: Text layer with typography information
  • ShapeLayer: Vector shape layer
  • SmartObjectLayer: Embedded or linked smart object
  • AdjustmentLayer: Non-destructive adjustment (curves, levels, etc.)

Layer hierarchy:

Layers are organized in a tree structure where groups can contain child layers. The GroupMixin provides iteration, indexing, and search capabilities:

# Iterate through all layers
for layer in psd:

print(layer.name) # Access by index first_layer = psd[0] # Check if layer is a specific type if layer.kind == 'pixel':
pixels = layer.numpy()


Common layer properties:

  • name: Layer name
  • visible: Visibility flag
  • opacity: Opacity (0-255)
  • blend_mode: Blend mode enum
  • bbox: Bounding box (left, top, right, bottom)
  • width, height: Dimensions
  • kind: Layer type string ('pixel', 'group', 'type', etc.)
  • parent: Parent layer or document

Layer operations:

  • composite(): Render layer to PIL Image
  • numpy(): Get pixel data as NumPy array
  • topil(): Convert to PIL Image
  • has_mask(): Check if layer has a mask
  • has_clip_layers(): Check if layer has clipping mask

Example usage:

from psd_tools import PSDImage
psd = PSDImage.open('document.psd')
# Access first layer
layer = psd[0]
# Modify layer properties
layer.visible = False
layer.opacity = 128
layer.name = "New Name"
# Get pixel data
pixels = layer.numpy()  # NumPy array
image = layer.topil()   # PIL Image
# Work with groups
for group in psd.descendants():

if group.kind == 'group':
print(f"Group: {group.name} with {len(group)} layers") # Composite specific layer rendered = layer.composite() rendered.save('layer.png')


Layer types are automatically determined from the underlying PSD structures and exposed through the kind property for easy type checking.

Layer

(left, top, right, bottom) tuple.

Blend mode of this layer. Writable.

Example:

from psd_tools.constants import BlendMode
if layer.blend_mode == BlendMode.NORMAL:

layer.blend_mode = BlendMode.SCREEN


BlendMode <#psd_tools.constants.BlendMode>.


Bottom coordinate.
int


Clip layers associated with this layer.
list of layers


Clipping flag for this layer. Writable.
bool


Deprecated. Use clipping property instead.

Composite layer and masks (mask, vector mask, and clipping layers).
  • viewport -- Viewport bounding box specified by (x1, y1, x2, y2) tuple. Default is the layer's bbox.
  • force -- Boolean flag to force vector drawing.
  • color -- Backdrop color specified by scalar or tuple of scalar. The color value should be in [0.0, 1.0]. For example, (1., 0., 0.) specifies red in RGB color mode.
  • alpha -- Backdrop alpha in [0.0, 1.0].
  • layer_filter -- Callable that takes a layer as argument and returns whether if the layer is composited. Default is is_visible().

PIL.Image.Image or None.


Deprecated: Use layer.parent.remove(layer) instead.

Layer effects.
Effects <#psd_tools.api.effects.Effects>


Fill opacity of this layer in [0, 255] range. Writable.
int


Returns True if the layer has associated clipping.
visible -- If True, check for visible clipping layers.
bool


Returns True if the layer has effects.
  • enabled -- If True, check for enabled effects.
  • name -- If given, check for specific effect type.

bool


Returns True if the layer has a mask.
bool


Returns True if the layer has live shape properties.
bool


Returns True if the layer has associated pixels. When this is True, topil method returns PIL.Image.Image.
bool


Returns True if the shape has a stroke.

Returns True if the layer has a vector mask.
bool


Height of the layer.
int


Return True if the layer is a group.
bool


Layer visibility. Takes group visibility in account.
bool


Kind of this layer, such as group, pixel, shape, type, smartobject, or psdimage. Class name without layer suffix.
str


Layer ID.
int layer id. if the layer is not assigned an id, -1.


Left coordinate. Writable.
int


Locks a layer accordind to the combination of flags.
lockflags -- An integer representing the locking state

Example using the constants of ProtectedFlags and bitwise or operation to lock both pixels and positions:

layer.lock(ProtectedFlags.COMPOSITE | ProtectedFlags.POSITION)



Returns mask associated with this layer.
Mask <#psd_tools.api.mask.Mask> or None


Moves the layer down a certain offset within the group the layer is in.
offset -- The number of positions to move the layer down (can be negative).
  • ValueError -- If layer has no parent or parent is not a group
  • IndexError -- If the new index is out of bounds

self


Deprecated: Use group.append(layer) instead.
group -- The group the current layer will be moved into.


Moves the layer up a certain offset within the group the layer is in.
offset -- The number of positions to move the layer up (can be negative).
  • ValueError -- If layer has no parent or parent is not a group
  • IndexError -- If the new index is out of bounds

self


Layer name. Writable.
str



Get NumPy array of the layer.
channel -- Which channel to return, can be 'color', 'shape', 'alpha', or 'mask'. Default is 'color+alpha'.
numpy.ndarray or None if there is no pixel.


(left, top) tuple. Writable.
tuple


Opacity of this layer in [0, 255] range. Writable.
int


Property for a list of live shapes or a line.

Some of the vector masks have associated live shape properties, that are Photoshop feature to handle primitive shapes such as a rectangle, an ellipse, or a line. Vector masks without live shape properties are plain path objects.

See psd_tools.api.shape <#module-psd_tools.api.shape>.

List of Invalidated <#psd_tools.api.shape.Invalidated>, Rectangle <#psd_tools.api.shape.Rectangle>, RoundedRectangle <#psd_tools.api.shape.RoundedRectangle>, Ellipse <#psd_tools.api.shape.Ellipse>, or Line <#psd_tools.api.shape.Line>.




Reference point of this layer as (x, y) tuple in the canvas coordinates. Writable.

Reference point is used for transformations such as rotation and scaling.

(x, y) tuple


Right coordinate.
int


(width, height) tuple.
tuple



Layer tagged blocks that is a dict-like container of settings.

See psd_tools.constants.Tag <#psd_tools.constants.Tag> for available keys.

TaggedBlocks <#psd_tools.psd.tagged_blocks.TaggedBlocks>.

Example:

from psd_tools.constants import Tag
metadata = layer.tagged_blocks.get_data(Tag.METADATA_SETTING)



Top coordinate. Writable.
int


Get PIL Image of the layer.
  • channel -- Which channel to return; e.g., 0 for 'R' channel in RGB image. See ChannelID <#psd_tools.constants.ChannelID>. When None, the method returns all the channels supported by PIL modes.
  • apply_icc -- Whether to apply ICC profile conversion to sRGB.

PIL.Image.Image, or None if the layer has no pixels.

Example:

from psd_tools.constants import ChannelID
image = layer.topil()
red = layer.topil(ChannelID.CHANNEL_0)
alpha = layer.topil(ChannelID.TRANSPARENCY_MASK)


Note:

Not all of the PSD image modes are supported in PIL.Image.Image. For example, 'CMYK' mode cannot include alpha channel in PIL. In this case, topil drops alpha channel.



Returns vector mask associated with this layer.
VectorMask <#psd_tools.api.shape.VectorMask> or None


Layer visibility. Doesn't take group visibility in account. Writable.
bool


Width of the layer.
int



Artboard

Artboard is a special kind of group that has a pre-defined viewbox.
(left, top, right, bottom) tuple.

Bottom coordinate (computed from children, read-only).

Left coordinate (computed from children, read-only).

Right coordinate (computed from children, read-only).

Top coordinate (computed from children, read-only).


Group

Group of layers.

Example:

group = psd[1]
for layer in group:

if layer.kind == 'pixel':
print(layer.name)



Bottom coordinate (computed from children, read-only).

Clipping flag for this layer. Writable.
bool


Composite layer and masks (mask, vector mask, and clipping layers).
  • viewport -- Viewport bounding box specified by (x1, y1, x2, y2) tuple. Default is the layer's bbox.
  • force -- Boolean flag to force vector drawing.
  • color -- Backdrop color specified by scalar or tuple of scalar. The color value should be in [0.0, 1.0]. For example, (1., 0., 0.) specifies red in RGB color mode.
  • alpha -- Backdrop alpha in [0.0, 1.0].
  • layer_filter -- Callable that takes a layer as argument and returns whether if the layer is composited. Default is is_visible().

PIL.Image.Image.


Returns a bounding box for layers or (0, 0, 0, 0) if the layers have no bounding box.
  • layers -- sequence of layers or a group.
  • include_invisible -- include invisible layers in calculation.

tuple of four int


Deprecated: Use psdimage.create_group(layer_list, name) instead.
  • parent -- The parent group to add the newly created Group object into.
  • layers -- The layers to group. Can by any subclass of Layer
  • name -- The display name of the group. Default to "Group".
  • open_folder -- Boolean defining whether the folder will be open or closed in photoshop. Default to True.

A Group
ValueError -- If layers is empty


Return True if the layer is a group.
bool


Left coordinate (computed from children, read-only).

Create a new Group object with minimal records and data channels and metadata to properly include the group in the PSD file.
  • name -- The display name of the group. Default to "Group".
  • open_folder -- Boolean defining whether the folder will be open or closed in photoshop. Default to True.
  • parent -- Optional parent folder to move the newly created group into.

A Group object
ValueError -- If parent is None


Returns True if the group is an open folder.
bool


Right coordinate (computed from children, read-only).

Top coordinate (computed from children, read-only).


PixelLayer

Layer that has rasterized image in pixels.

Example:

assert layer.kind == 'pixel':
image = layer.composite()
image.save('layer.png')


Create a PixelLayer from a PIL image for a given psd file.
  • image -- The Image object to convert to photoshop
  • psdimage -- The target psdimage the image will be converted for.
  • name -- The name of the layer. Defaults to "Layer"
  • top -- Pixelwise offset from the top of the canvas for the new layer.
  • left -- Pixelwise offset from the left of the canvas for the new layer.
  • compression -- Compression algorithm to use for the data.

A PixelLayer object
TypeError -- If image is not a PIL Image or parent is None



ShapeLayer

Layer that has drawing in vector mask.
(left, top, right, bottom) tuple.

Bottom coordinate.
int


Left coordinate. Writable.
int


Right coordinate.
int


Top coordinate. Writable.
int



SmartObjectLayer

Layer that inserts external data.

Use smart_object attribute to get the external data. See SmartObject <#psd_tools.api.smart_object.SmartObject>.

Example:

import io
if layer.smart_object.filetype == 'jpg':

image = Image.open(io.BytesIO(layer.smart_object.data))


Associated smart object.
SmartObject <#psd_tools.api.smart_object.SmartObject>.



TypeLayer

Layer that has text and styling information for fonts or paragraphs.

Text is accessible at text property. Styling information for paragraphs is in engine_dict. Document styling information such as font list is is resource_dict.

Currently, textual information is read-only.

Example:

if layer.kind == 'type':

print(layer.text)
print(layer.engine_dict['StyleRun'])
# Extract font for each substring in the text.
text = layer.engine_dict['Editor']['Text'].value
fontset = layer.resource_dict['FontSet']
runlength = layer.engine_dict['StyleRun']['RunLengthArray']
rundata = layer.engine_dict['StyleRun']['RunArray']
index = 0
for length, style in zip(runlength, rundata):
substring = text[index:index + length]
stylesheet = style['StyleSheet']['StyleSheetData']
font = fontset[stylesheet['Font']]
print('%r gets %s' % (substring, font))
index += length





Text in the layer. Read-only.

Note:

New-line character in Photoshop is '\r'.



Text type. Read-only.


None if text type cannot be determined or information is unavailable


See psd_tools.constants.TextType <#psd_tools.constants.TextType>.


Matrix (xx, xy, yx, yy, tx, ty) applies affine transformation.



psd_tools.api.mask

Mask module.

Mask

Mask data attached to a layer.

There are two distinct internal mask data: user mask and vector mask. User mask refers any pixel-based mask whereas vector mask refers a mask from a shape path. Internally, two masks are combined and referred real mask.

Background color.


Bottom coordinate.

Return raw mask data, or None if no data.



Return True if the mask has real flags.


Left coordinate.



Right coordinate.

(Width, Height) tuple.

Top coordinate.

Get PIL Image of the mask.
real -- When True, returns pixel + vector mask combined.
PIL Image object, or None if the mask is empty.




psd_tools.api.shape

Shape module.

In PSD/PSB, shapes are all represented as VectorMask in each layer, and optionally there might be Origination object to control live shape properties and Stroke to specify how outline is stylized.

VectorMask

Vector mask data.

Vector mask is a resolution-independent mask that consists of one or more Path objects. In Photoshop, all the path objects are represented as Bezier curves. Check paths property for how to deal with path objects.

Bounding box tuple (left, top, right, bottom) in relative coordinates, where top-left corner is (0., 0.) and bottom-right corner is (1., 1.).
tuple


Clipboard record containing bounding box information.

Depending on the Photoshop version, this field can be None.


If the mask is disabled.

Initial fill rule.

When 0, fill inside of the path. When 1, fill outside of the shape.

int


Invert the mask.

If the knots are not linked.

List of Subpath <#psd_tools.psd.vector.Subpath>. Subpath is a list-like structure that contains one or more Knot <#psd_tools.psd.vector.Knot> items. Knot contains relative coordinates of control points for a Bezier curve. index <#psd_tools.psd.vector.Subpath.index> indicates which origination item the subpath belongs, and operation <#psd_tools.psd.vector.Subpath.operation> indicates how to combine multiple shape paths.

In PSD, path fill rule is even-odd.

Example:

for subpath in layer.vector_mask.paths:

anchors = [(
int(knot.anchor[1] * psd.width),
int(knot.anchor[0] * psd.height),
) for knot in subpath]


List of Subpath.



Stroke

Stroke contains decorative information for strokes.

This is a thin wrapper around Descriptor <#psd_tools.psd.descriptor.Descriptor> structure. Check _data attribute to get the raw data.


Fill effect.

If the stroke is enabled.

If the stroke fill is enabled.

Alignment, one of inner, outer, center.

Cap type, one of butt, round, square.

Line dash offset in float.
float


Line dash set in list of UnitFloat.
list


Join type, one of miter, round, bevel.

Stroke width in float.

Miter limit in float.

Opacity value.



Origination

Origination keeps live shape properties for some of the primitive shapes. Origination objects are accessible via origination <#psd_tools.api.layers.Layer.origination> property of layers. Following primitive shapes are defined: Invalidated, Line, Rectangle, Ellipse, and RoundedRectangle.

Invalidated

Invalidated live shape.

This equals to a primitive shape that does not provide Live shape properties. Use VectorMask to access shape information instead of this origination object.



Line

Line live shape.

Line arrow end.
bool


Line arrow length.
float


Line arrow start.
bool


Line arrow width.
float


Bounding box of the live shape.
Descriptor <#psd_tools.psd.descriptor.Descriptor>


Origination item index.
int



Line end.
Descriptor <#psd_tools.psd.descriptor.Descriptor>


Line start.
Descriptor <#psd_tools.psd.descriptor.Descriptor>



Type of the vector shape.
  • 1: Rectangle
  • 2: RoundedRectangle
  • 4: Line
  • 5: Ellipse

int




Ellipse

Ellipse live shape.
Bounding box of the live shape.
Descriptor <#psd_tools.psd.descriptor.Descriptor>


Origination item index.
int



Type of the vector shape.
  • 1: Rectangle
  • 2: RoundedRectangle
  • 4: Line
  • 5: Ellipse

int




Rectangle

Rectangle live shape.
Bounding box of the live shape.
Descriptor <#psd_tools.psd.descriptor.Descriptor>


Origination item index.
int



Type of the vector shape.
  • 1: Rectangle
  • 2: RoundedRectangle
  • 4: Line
  • 5: Ellipse

int




RoundedRectangle

Rounded rectangle live shape.
Bounding box of the live shape.
Descriptor <#psd_tools.psd.descriptor.Descriptor>


Origination item index.
int



Type of the vector shape.
  • 1: Rectangle
  • 2: RoundedRectangle
  • 4: Line
  • 5: Ellipse

int


Corner radii of rounded rectangles. The order is top-left, top-right, bottom-left, bottom-right.
Descriptor <#psd_tools.psd.descriptor.Descriptor>




psd_tools.api.smart_object

Smart object module.

SmartObject

Smart object that represents embedded or external file.

Smart objects are attached to SmartObjectLayer <#psd_tools.api.layers.SmartObjectLayer>.

Embedded file content, or empty if kind is external or alias

Original file name of the object.

File size of the object.

Preferred file extension, such as jpg.

Return True if the file is embedded PSD/PSB.

Kind of the link, 'data', 'alias', or 'external'.

Open the smart object as binary IO.
external_dir -- Path to the directory of the external file.

Example:

with layer.smart_object.open() as f:

data = f.read()



Resolution of the object.

Save the smart object to a file.
filename -- File name to export. If None, use the embedded name.


A tuple representing the coordinates of the smart objects's transformed box. This box is the result of one or more transformations such as scaling, rotation, translation, or skewing to the original bounding box of the smart object.

The format of the tuple is as follows: (x1, y1, x2, y2, x3, y3, x4, y4)

Where 1 is top left corner, 2 is top right, 3 is bottom right and 4 is bottom left.


UUID of the object.

Warp parameters.


psd_tools.composite

Composite module for layer rendering and blending.

This subpackage provides the rendering engine for compositing PSD layers into raster images. It implements Photoshop's blend modes, layer effects, and vector shape rasterization.

Note: This module requires optional dependencies. Install with:

pip install 'psd-tools[composite]'


Or using uv:

uv sync --extra composite


The composite extra includes:

  • aggdraw: For vector path and bezier curve rasterization
  • scipy: For advanced image processing operations
  • scikit-image: For morphological operations in effects

Key modules:

  • psd_tools.composite.composite: Main compositing functions
  • psd_tools.composite.blend: Blend mode implementations
  • psd_tools.composite.effects: Layer effects (stroke, shadow, etc.)
  • psd_tools.composite.vector: Vector shape and path rendering
  • psd_tools.composite.paint: Fill rendering (gradients, patterns)

Example usage:

from psd_tools import PSDImage
psd = PSDImage.open('document.psd')
# Composite entire document to PIL Image
image = psd.composite()
image.save('output.png')
# Composite specific layer
layer_image = psd[0].composite()


The compositing engine uses NumPy arrays for efficient pixel manipulation and supports all of Photoshop's standard blend modes including multiply, screen, overlay, soft light, and more.

Performance considerations:

  • Compositing can be memory-intensive for large documents
  • Vector shapes require aggdraw for accurate rendering
  • Some effects have limited support compared to Photoshop

This module provides layer rendering and compositing functionality.

Installation: Requires optional dependencies:

pip install psd-tools[composite]


Or with uv:

uv sync --extra composite


Composite Functions

Composite layers and return NumPy arrays.

This function composites the given layer or document into NumPy arrays representing color, shape, and alpha channels. It applies layer blending, effects, masks, and clipping according to the PSD specification.

group: Layer or PSDImage to composite color: Initial backdrop color (0.0-1.0, default: 1.0). Can be:
  • Scalar (float): Applied to all channels
  • Tuple: Per-channel values (R,G,B or C,M,Y,K)
  • ndarray: Full backdrop image



alpha: Initial backdrop alpha (0.0-1.0, default: 0.0). Can be scalar or ndarray viewport: Bounding box (left, top, right, bottom) to composite. If None, uses layer bounds layer_filter: Optional callable(layer) -> bool to filter which layers to composite force: If True, force re-rendering of all layers including vector shapes and fills as_layer: If True, treat the group as a layer (apply blend mode to backdrop)

  • color: RGB/CMYK/Grayscale values in range [0.0, 1.0]
  • shape: Layer shape/coverage mask in range [0.0, 1.0]
  • alpha: Composite alpha channel in range [0.0, 1.0]


>>> from psd_tools import PSDImage
>>> psd = PSDImage.open('example.psd')
>>> color, shape, alpha = composite(psd)
>>> # Apply custom backdrop
>>> color, shape, alpha = composite(psd, color=(1.0, 0.0, 0.0), alpha=1.0)
>>> # Force re-render vector layers
>>> color, shape, alpha = composite(psd, force=True)
>>> # Composite only visible layers
>>> color, shape, alpha = composite(psd, layer_filter=lambda l: l.visible)
    
  • Vector shape rendering (aggdraw)
  • Gradient fills (scipy)
  • Layer effects (scikit-image)


  • Adjustment layers have limited support
  • Text rendering is not supported (text layers show as raster if available)



Composite layers and return a PIL Image.

This function composites the given layer or document into a PIL Image, applying blend modes, effects, and color management.

layer: Layer or PSDImage to composite color: Initial backdrop color (0.0-1.0). Can be scalar, tuple, or ndarray alpha: Initial backdrop alpha (0.0-1.0). Can be scalar or ndarray viewport: Bounding box (left, top, right, bottom) to composite. If None, uses layer bounds layer_filter: Optional callable to filter which layers to composite. Should return True to include force: If True, force re-rendering of all layers (ignore cached pixels) as_layer: If True, apply layer blend modes (default: False for document-level compositing) apply_icc: If True, apply ICC profile color correction (default: True)
PIL Image with composited result, or None if viewport is empty
  • Requires optional composite dependencies (aggdraw, scipy, scikit-image)
  • LAB and Duotone color modes have limited blending support
  • Alpha channel handling varies by color mode



Blend Modes

Blend mode implementations.

This module implements Photoshop's blend modes for compositing layers. Blend modes determine how a layer's colors interact with the layers beneath it. Each function implements the mathematical formula for a specific blend mode.

The blend functions operate on NumPy arrays with normalized float32 values (0.0-1.0) representing pixel color channels. They follow Adobe's PDF Blend Mode specification.

Blend mode categories:

Normal modes: - normal: Source replaces backdrop (no blending)

Darken modes: - darken: Selects darker of source and backdrop - multiply: Multiplies colors (darkens) - color_burn: Darkens backdrop to reflect source - linear_burn: Similar to multiply but more extreme - darker_color: Selects darker color (non-separable)

Lighten modes: - lighten: Selects lighter of source and backdrop - screen: Inverted multiply (lightens) - color_dodge: Brightens backdrop to reflect source - linear_dodge: Same as addition (Add blend mode) - lighter_color: Selects lighter color (non-separable)

Contrast modes: - overlay: Combination of multiply and screen - soft_light: Soft version of overlay - hard_light: Hard version of overlay - vivid_light: Combination of color dodge and burn - linear_light: Combination of linear dodge and burn - pin_light: Replaces colors based on brightness - hard_mix: Posterizes to primary colors

Inversion modes: - difference: Absolute difference between colors - exclusion: Similar to difference but lower contrast

Component modes (non-separable): - hue: Preserves luminosity and saturation, replaces hue - saturation: Preserves luminosity and hue, replaces saturation - color: Preserves luminosity, replaces hue and saturation - luminosity: Preserves hue and saturation, replaces luminosity

Implementation details:

  • Separable blend modes process each color channel independently
  • Non-separable modes convert to HSL color space first
  • All functions expect normalized float32 arrays (0.0-1.0 range)
  • Division by zero is protected with small epsilon values

Example usage:

import numpy as np
from psd_tools.composite.blend import multiply, screen
# Create backdrop and source colors (normalized)
backdrop = np.array([0.5, 0.3, 0.8], dtype=np.float32)
source = np.array([0.7, 0.6, 0.2], dtype=np.float32)
# Apply blend mode
result = multiply(backdrop, source)
# Result: [0.35, 0.18, 0.16]


The BLEND_FUNC dictionary maps BlendMode <#psd_tools.constants.BlendMode> enums to their corresponding functions for easy lookup during compositing.

Looks at the color information in each channel and divides the blend color from the base color.

Adds the red, green and blue channel values of the blend color to the RGB values of the base color. If the resulting sum for a channel is 255 or greater, it receives a value of 255; if less than 255, a value of 0. Therefore, all blended pixels have red, green, and blue channel values of either 0 or 255. This changes all pixels to primary additive colors (red, green, or blue), white, or black.

Burns or dodges the colors by decreasing or increasing the brightness, depending on the blend color. If the blend color (light source) is lighter than 50% gray, the image is lightened by increasing the brightness. If the blend color is darker than 50% gray, the image is darkened by decreasing the brightness.

Wrap non-separable blending function for CMYK handling.

Replaces the colors, depending on the blend color. If the blend color (light source) is lighter than 50% gray, pixels darker than the blend color are replaced, and pixels lighter than the blend color do not change. If the blend color is darker than 50% gray, pixels lighter than the blend color are replaced, and pixels darker than the blend color do not change. This is useful for adding special effects to an image.

Burns or dodges the colors by increasing or decreasing the contrast, depending on the blend color. If the blend color (light source) is lighter than 50% gray, the image is lightened by decreasing the contrast. If the blend color is darker than 50% gray, the image is darkened by increasing the contrast.

The blend module implements Photoshop's blend modes following the Adobe PDF specification. All blend functions operate on normalized float32 NumPy arrays.

Vector Rendering

Vector shapes and path operations for compositing.

Draw a stroke.

Requires aggdraw for bezier curve rasterization.


Draw a vector mask.

Requires aggdraw for bezier curve rasterization.


Vector shape and path rendering using aggdraw for bezier curve rasterization.

Effects Rendering

Layer effects rendering.

This module implements rendering for Photoshop layer effects (also known as layer styles). Effects are non-destructive visual enhancements applied to layers such as strokes, shadows, glows, and overlays.

Note: Effects rendering requires scikit-image. Install with:

pip install 'psd-tools[composite]'


Currently supported effects:

Stroke: Outline around layer shape or pixels - Supports solid color, gradient, and pattern fills - Position: inside, outside, or centered - Limited compared to Photoshop's full implementation

Partially supported or limited effects:

  • Drop shadow, inner shadow, outer glow, inner glow
  • These may render but with reduced accuracy

The main function draw_stroke_effect() handles stroke rendering by:

1.
Extracting the layer's alpha channel or shape mask
2.
Applying morphological operations (dilation/erosion) based on stroke size and position
3.
Filling the stroke region with the specified paint (solid color, gradient, pattern)
4.
Returning the rendered stroke as a NumPy array

Implementation notes:

  • Effects are image-based rather than vector-based, which may differ from Photoshop
  • For layers with vector paths, ideally strokes should be drawn geometrically
  • Some effect parameters may not be fully supported
  • Complex effect combinations may not render identically to Photoshop

Example usage (internal):

from psd_tools.composite.effects import draw_stroke_effect
# Called during layer compositing
viewport = (0, 0, 100, 100)  # Region to render
shape = layer_alpha_channel    # NumPy array
desc = stroke_descriptor       # Effect parameters
color, alpha = draw_stroke_effect(viewport, shape, desc, psd)


The effects system integrates with the main compositing pipeline and is automatically applied when rendering layers that have effects enabled.

Layer effects rendering including strokes, shadows, and glows. Requires scikit-image for morphological operations.

psd_tools.compression

Image compression utilities for PSD channel data.

This subpackage provides compression and decompression codecs for raw pixel data in PSD files. Adobe Photoshop supports multiple compression methods for channel data to reduce file size.

Supported compression methods:

  • RAW (Compression.RAW): Uncompressed raw pixel data
  • RLE (Compression.RLE): Apple PackBits run-length encoding
  • ZIP (Compression.ZIP): ZIP/Deflate compression without prediction
  • ZIP_WITH_PREDICTION (Compression.ZIP_WITH_PREDICTION): ZIP with delta encoding

The RLE codec includes both a pure Python implementation and a Cython-optimized version (_rle.pyx) that provides significant performance improvements. The Cython version is used automatically when available, with graceful fallback to pure Python.

Key functions:

  • compress(): Compress raw pixel data using specified method
  • decompress(): Decompress pixel data back to raw bytes
  • encode_rle(): RLE encoding for a single channel
  • decode_rle(): RLE decoding for a single channel

Example usage:

from psd_tools.compression import compress, decompress
from psd_tools.constants import Compression
# Compress raw channel data
compressed = compress(

data=raw_pixels,
compression=Compression.RLE,
width=100,
height=100,
depth=8,
version=1 ) # Decompress back to raw data raw_pixels = decompress(
data=compressed,
compression=Compression.RLE,
width=100,
height=100,
depth=8,
version=1 )


Performance notes:

  • RLE is most effective for images with large uniform areas
  • ZIP with prediction works well for continuous-tone images
  • The Cython RLE codec can be 10-100x faster than pure Python
  • Compression method is chosen per-channel when saving PSD files

The compression module handles various bit depths (8, 16, 32-bit per channel) and implements delta encoding for improved compression ratios on certain image types.

This module provides compression and decompression codecs for PSD channel data.

Compression Functions

Compress raw data.
  • data -- raw data bytes to write.
  • compression -- compression type, see Compression <#psd_tools.constants.Compression>.
  • width -- width.
  • height -- height.
  • depth -- bit depth of the pixel.
  • version -- psd file version.

compressed data bytes.


Decompress raw data.
  • data -- compressed data bytes.
  • compression -- compression type, see Compression <#psd_tools.constants.Compression>.
  • width -- width.
  • height -- height.
  • depth -- bit depth of the pixel.
  • version -- psd file version.

decompressed data bytes.


RLE Codec



The RLE (Run-Length Encoding) codec implements Apple PackBits compression. A Cython-optimized version (_rle.pyx) is used when available, providing 10-100x performance improvement over the pure Python fallback.

Prediction Encoding



Prediction encoding applies delta compression before ZIP compression, improving compression ratios for continuous-tone images. Supports 8, 16, and 32-bit depths.

psd_tools.constants

Various constants for psd_tools

BlendMode


ChannelID


Clipping


ColorMode


ColorSpaceID


CompatibilityMode

Compatibility modes that describe how compositing and layer control should attempt to behave.







Compression

Compression modes.

Compression. 0 = Raw Data, 1 = RLE compressed, 2 = ZIP without prediction, 3 = ZIP with prediction.






EffectOSType


GlobalLayerMaskKind


LinkedLayerType


PathResourceID


PlacedLayerType


PrintScaleStyle


Resource

Image resource keys.

Note the following is not defined for performance reasons.

  • PATH_INFO_10 to PATH_INFO_989 corresponding to 2010 - 2989








































































































































SectionDivider


Tag

Tagged blocks keys.































































































TextType


psd_tools.psd

Low-level API that translates binary data to Python structure.

All the data structure in this subpackage inherits from one of the object defined in psd_tools.psd.base <#module-psd_tools.psd.base> module.

PSD

Low-level PSD file structure that resembles the specification <https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/>.

Example:

from psd_tools.psd import PSD
with open(input_file, 'rb') as f:

psd = PSD.read(f) with open(output_file, 'wb') as f:
psd.write(f)


See FileHeader <#psd_tools.psd.header.FileHeader>.

See ColorModeData <#psd_tools.psd.color_mode_data.ColorModeData>.

See ImageResources <#psd_tools.psd.image_resources.ImageResources>.

See LayerAndMaskInformation <#psd_tools.psd.layer_and_mask.LayerAndMaskInformation>.

See ImageData <#psd_tools.psd.image_data.ImageData>.


psd_tools.psd.base

Base data structures intended for inheritance.

All the data objects in this subpackage inherit from the base classes here. That means, all the data structures in the psd_tools.psd <#module-psd_tools.psd> subpackage implements the methods of BaseElement for serialization and decoding.

Objects that inherit from the BaseElement typically gets attrs <https://www.attrs.org/en/stable/index.html> decoration to have data fields.

BaseElement

Base element of various PSD file structs. All the data objects in psd_tools.psd <#module-psd_tools.psd> subpackage inherit from this class.
Read the element from a file-like object.

Write the element to a file-like object.


Write the element to bytes.

Validate the attribute.


EmptyElement

Empty element that does not have a value.

ValueElement

Single value wrapper that has a value attribute.

Pretty printing shows the internal value by default. Inherit with @define(repr=False) decorator to keep this behavior.

Internal value.


NumericElement

Single value element that has a numeric value attribute.

IntegerElement

Single integer value element that has a value attribute.

Use with @define(repr=False) decorator.


ShortIntegerElement

Single short integer element that has a value attribute.

Use with @define(repr=False) decorator.


ByteElement

Single 1-byte integer element that has a value attribute.

Use with @define(repr=False) decorator.


BooleanElement

Single bool value element that has a value attribute.

Use with @define(repr=False) decorator.


StringElement


ListElement

List-like element that has items list.

DictElement

Dict-like element that has items OrderedDict.

psd_tools.psd.color_mode_data

Color mode data structure.

ColorModeData

Color mode data section of the PSD file.

For indexed color images the data is the color table for the image in a non-interleaved order.

Duotone images also have this data, but the data format is undocumented.

Returns interleaved color table in bytes.


psd_tools.psd.descriptor

Descriptor data structure.

Descriptors are basic data structure used throughout PSD files. Descriptor is one kind of serialization protocol for data objects, and enum classes in psd_tools.terminology <#module-psd_tools.terminology> or bytes indicates what kind of descriptor it is.

The class ID can be pre-defined enum if the tag is 4-byte length or plain bytes if the length is arbitrary. They depend on the internal version of Adobe Photoshop but the detail is unknown.

Pretty printing is the best approach to check the descriptor content:

from IPython.pretty import pprint
pprint(descriptor)


Alias


Bool


Class

Class structure.
str value

bytes in Klass <#psd_tools.terminology.Klass>


Class1


Class2


Class3


Descriptor

Dict-like descriptor structure.

Key values can be 4-character bytes in Key <#psd_tools.terminology.Key> or arbitrary length bytes. Supports direct access by Key <#psd_tools.terminology.Key>.

Example:

from psd_tools.terminology import Key
descriptor[Key.Enabled]
for key in descriptor:

print(descriptor[key])


str

bytes in Klass <#psd_tools.terminology.Klass>


Double


Enumerated

Enum structure.
bytes in Type <#psd_tools.terminology.Type>

bytes in Enum <#psd_tools.terminology.Enum>

Get enum name.


EnumeratedReference

Enumerated reference structure.
str value

bytes in Klass <#psd_tools.terminology.Klass>

bytes in Type <#psd_tools.terminology.Type>

bytes in Enum <#psd_tools.terminology.Enum>


GlobalObject


Identifier

Identifier equivalent to Integer.

Index

Index equivalent to Integer.

Integer


LargeInteger


List

List structure.

Example:

for item in list_value:

print(item)



Name

Name structure (Undocumented).
str

bytes in Klass <#psd_tools.terminology.Klass>

str


ObjectArray

Object array structure almost equivalent to Descriptor.
int value

str value

bytes in Klass <#psd_tools.terminology.Klass>


Property

Property structure.
str value

bytes in Klass <#psd_tools.terminology.Klass>

bytes in Key <#psd_tools.terminology.Key>


Offset

Offset structure.
str value

bytes in Klass <#psd_tools.terminology.Klass>

int value


Path

Undocumented path structure equivalent to RawData.

RawData


Reference

Reference structure equivalent to List.

String


UnitFloat


UnitFloats


psd_tools.psd.engine_data

EngineData structure.

PSD file embeds text formatting data in its own markup language referred EngineData. The format looks like the following:

<<

/EngineDict
<<
/Editor
<<
/Text (˛ˇMake a change and save.)
>>
>>
/Font
<<
/Name (˛ˇHelveticaNeue-Light)
/FillColor
<<
/Type 1
/Values [ 1.0 0.0 0.0 0.0 ]
>>
/StyleSheetSet [
<<
/Name (˛ˇNormal RGB)
>>
]
>> >>


EngineData

Dict-like element.

TYPE_TOOL_OBJECT_SETTING tagged block contains this object in its descriptor.


EngineData2

Dict-like element.

TEXT_ENGINE_DATA tagged block has this object.


Bool


Dict


Float


Integer


List


Property


String


psd_tools.psd.effects_layer

Effects layer structure.

Note the structures in this module is obsolete and object-based layer effects are stored in tagged blocks.

EffectsLayer

Dict-like EffectsLayer structure. See psd_tools.constants.EffectOSType <#psd_tools.constants.EffectOSType> for available keys.


CommonStateInfo


ShadowInfo


OuterGlowInfo


InnerGlowInfo


BevelInfo


SolidFillInfo


psd_tools.psd.filter_effects

Filter effects structure.

FilterEffects


FilterEffect


FilterEffectChannel


FilterEffectExtra


psd_tools.psd.header

File header structure.

FileHeader

Header section of the PSD file.

Example:

from psd_tools.psd.header import FileHeader
from psd_tools.constants import ColorMode
header = FileHeader(channels=2, height=359, width=400, depth=8,

color_mode=ColorMode.GRAYSCALE)


Signature: always equal to b'8BPS'.

Version number. PSD is 1, and PSB is 2.

The number of channels in the image, including any user-defined alpha channel.

The height of the image in pixels.

The width of the image in pixels.

The number of bits per channel.

The color mode of the file. See ColorMode <#psd_tools.constants.ColorMode>


psd_tools.psd.image_data

Image data section structure.

ImageData corresponds to the last section of the PSD/PSB file where a composited image is stored. When the file does not contain layers, this is the only place pixels are saved.

ImageData

Merged channel image data.
See Compression <#psd_tools.constants.Compression>.

bytes as compressed in the compression flag.

Get decompressed data.
header -- See FileHeader <#psd_tools.psd.header.FileHeader>.
list of bytes corresponding each channel.


Create a new image data object.
  • header -- FileHeader.
  • compression -- compression type.
  • color -- default color. int or iterable for channel length.



Set raw data and compress.
  • data -- list of raw data bytes corresponding channels.
  • compression -- compression type, see Compression <#psd_tools.constants.Compression>.
  • header -- See FileHeader <#psd_tools.psd.header.FileHeader>.

length of compressed data.



psd_tools.psd.image_resources

Image resources section structure. Image resources are used to store non-pixel data associated with images, such as pen tool paths or slices.

See Resource <#psd_tools.constants.Resource> to check available resource names.

Example:

from psd_tools.constants import Resource
version_info = psd.image_resources.get_data(Resource.VERSION_INFO)


The following resources are plain bytes:

Resource.OBSOLETE1: 1000
Resource.MAC_PRINT_MANAGER_INFO: 1001
Resource.MAC_PAGE_FORMAT_INFO: 1002
Resource.OBSOLETE2: 1003
Resource.DISPLAY_INFO_OBSOLETE: 1007
Resource.BORDER_INFO: 1009
Resource.DUOTONE_IMAGE_INFO: 1018
Resource.EFFECTIVE_BW: 1019
Resource.OBSOLETE3: 1020
Resource.EPS_OPTIONS: 1021
Resource.QUICK_MASK_INFO: 1022
Resource.OBSOLETE4: 1023
Resource.WORKING_PATH: 1025
Resource.OBSOLETE5: 1027
Resource.IPTC_NAA: 1028
Resource.IMAGE_MODE_RAW: 1029
Resource.JPEG_QUALITY: 1030
Resource.URL: 1035
Resource.COLOR_SAMPLERS_RESOURCE_OBSOLETE: 1038
Resource.ICC_PROFILE: 1039
Resource.SPOT_HALFTONE: 1043
Resource.JUMP_TO_XPEP: 1052
Resource.EXIF_DATA_1: 1058
Resource.EXIF_DATA_3: 1059
Resource.XMP_METADATA: 1060
Resource.CAPTION_DIGEST: 1061
Resource.ALTERNATE_DUOTONE_COLORS: 1066
Resource.ALTERNATE_SPOT_COLORS: 1067
Resource.HDR_TONING_INFO: 1070
Resource.PRINT_INFO_CS2: 1071
Resource.COLOR_SAMPLERS_RESOURCE: 1073
Resource.DISPLAY_INFO: 1077
Resource.MAC_NSPRINTINFO: 1084
Resource.WINDOWS_DEVMODE: 1085
Resource.PATH_INFO_N: 2000-2999
Resource.PLUGIN_RESOURCES_N: 4000-4999
Resource.IMAGE_READY_VARIABLES: 7000
Resource.IMAGE_READY_DATA_SETS: 7001
Resource.IMAGE_READY_DEFAULT_SELECTED_STATE: 7002
Resource.IMAGE_READY_7_ROLLOVER_EXPANDED_STATE: 7003
Resource.IMAGE_READY_ROLLOVER_EXPANDED_STATE: 7004
Resource.IMAGE_READY_SAVE_LAYER_SETTINGS: 7005
Resource.IMAGE_READY_VERSION: 7006
Resource.LIGHTROOM_WORKFLOW: 8000


ImageResources

Image resources section of the PSD file. Dict of ImageResource.
Get data from the image resources.

Shortcut for the following:

if key in image_resources:

value = tagged_blocks[key].data



Create a new default image resouces.
ImageResources



ImageResource

Image resource block.
Binary signature, always b'8BIM'.

Unique identifier for the resource. See Resource <#psd_tools.constants.Resource>.


The resource data.


AlphaIdentifiers


AlphaNamesPascal


AlphaNamesUnicode


Byte


GridGuidesInfo


HalftoneScreens


HalftoneScreen


Integer


LayerGroupEnabledIDs


LayerGroupInfo


LayerSelectionIDs


ShortInteger


PascalString


PixelAspectRatio


PrintFlags


PrintFlagsInfo


PrintScale


ResoulutionInfo


Slices


SlicesV6


SliceV6


ThumbnailResource


ThumbnailResourceV4


TransferFunctions


TransferFunction


URLList


URLItem


VersionInfo


psd_tools.psd.layer_and_mask

Layer and mask data structures.

This module implements the low-level binary structures for PSD layers and masks, corresponding to the "Layer and Mask Information" section of PSD files. This is one of the most complex parts of the PSD format.

Key classes:

  • LayerAndMaskInformation: Top-level container for all layer data
  • LayerInfo: Contains layer records and channel image data
  • LayerRecords: List of individual layer records
  • LayerRecord: Single layer metadata (name, bounds, blend mode, etc.)
  • ChannelInfo: Channel metadata within a layer record
  • ChannelImageData: Compressed pixel data for all channels
  • ChannelData: Single channel's compressed pixel data
  • MaskData: Layer mask parameters
  • GlobalLayerMaskInfo: Document-wide mask settings
  • TaggedBlocks: Extended layer metadata (see psd_tools.psd.tagged_blocks <#module-psd_tools.psd.tagged_blocks>)

The layer structure in PSD files is stored as a flat list with implicit hierarchy. Group boundaries are marked by special layers with SectionDivider tagged blocks:

  • BOUNDING_SECTION_DIVIDER: Marks the start of a group (the layer that opens the group)
  • OPEN_FOLDER or CLOSED_FOLDER: Marks the end of a group (the closing divider layer) - OPEN_FOLDER: Group was open in Photoshop UI - CLOSED_FOLDER: Group was closed in Photoshop UI

The high-level API (psd_tools.api <#module-psd_tools.api>) reconstructs this into a proper tree structure with parent-child relationships.

Each layer record contains:

1.
Metadata: Rectangle bounds, blend mode, opacity, flags
2.
Channel info: List of channels (R, G, B, A, masks, etc.) with byte offsets
3.
Blend ranges: Advanced blending parameters
4.
Layer name: Pascal string (legacy, inaccurate for Unicode names)
5.
Tagged blocks: Extended metadata in key-value format

The channel image data section follows all layer records and contains the actual compressed pixel data for each channel, referenced by the channel info structures.

Example of reading layer metadata:

from psd_tools.psd import PSD
with open('file.psd', 'rb') as f:

psd = PSD.read(f) layer_info = psd.layer_and_mask_information.layer_info for record in layer_info.layer_records:
print(f"Layer: {record.name}")
print(f" Bounds: {record.top}, {record.left}, {record.bottom}, {record.right}")
print(f" Blend mode: {record.blend_mode}")
print(f" Channels: {len(record.channel_info)}")


For most use cases, prefer the high-level Layer <#psd_tools.api.layers.Layer> API which provides easier access to this data.

LayerAndMaskInformation


LayerInfo

High-level organization of the layer information.
Layer count. If it is a negative number, its absolute value is the number of layers and the first alpha channel contains the transparency data for the merged result.

Information about each layer. See LayerRecords.

Channel image data. See ChannelImageData.


GlobalLayerMaskInfo

Global mask information.
Overlay color space (undocumented) and color components.

Opacity. 0 = transparent, 100 = opaque.

Kind. 0 = Color selected--i.e. inverted; 1 = Color protected; 128 = use value stored per layer. This value is preferred. The others are for backward compatibility with beta versions.


LayerRecords

List of layer records. See LayerRecord.

LayerRecord

Layer record.
Top position.

Left position.

Bottom position.

Right position.

List of ChannelInfo.

Blend mode signature b'8BIM'.

Blend mode key. See BlendMode <#psd_tools.constants.BlendMode>.

Opacity, 0 = transparent, 255 = opaque.

Clipping, 0 = base, 1 = non-base. See Clipping <#psd_tools.constants.Clipping>.

See LayerFlags.

MaskData or None.

See LayerBlendingRanges.

Layer name.

See TaggedBlocks <#psd_tools.psd.tagged_blocks.TaggedBlocks>.

List of channel sizes: [(width, height)].

Height of the layer.

Width of the layer.


LayerFlags


LayerBlendingRanges

Layer blending ranges.

All ranges contain 2 black values followed by 2 white values.

List of composite gray blend source and destination ranges.

List of channel source and destination ranges.


MaskData

Mask data.

Real user mask is a final composite mask of vector and pixel masks.

Top position.

Left position.

Bottom position.

Right position.

Default color. 0 or 255.

See MaskFlags.

MaskParameters or None.

Real user mask flags. See MaskFlags.

Real user mask background. 0 or 255.

Top position of real user mask.

Left position of real user mask.

Bottom position of real user mask.

Right position of real user mask.

Height of the mask.

Height of real user mask.

Width of real user mask.

Width of the mask.


MaskFlags


MaskParameters


ChannelInfo

Channel information.
Channel ID: 0 = red, 1 = green, etc.; -1 = transparency mask; -2 = user supplied layer mask, -3 real user supplied layer mask (when both a user mask and a vector mask are present). See ChannelID <#psd_tools.constants.ChannelID>.

Length of the corresponding channel data.


ChannelImageData

List of channel data list.

This size of this list corresponds to the size of LayerRecords. Each item corresponds to the channels of each layer.

See ChannelDataList.


ChannelDataList

List of channel image data, corresponding to each color or alpha.

See ChannelData.


ChannelData

Channel data.
Compression type. See Compression <#psd_tools.constants.Compression>.

Data.

Get decompressed channel data.
  • width -- width.
  • height -- height.
  • depth -- bit depth of the pixel.
  • version -- psd file version.

bytes


Set raw channel data and compress to store.
  • data -- raw data bytes to write.
  • compression -- compression type, see Compression <#psd_tools.constants.Compression>.
  • width -- width.
  • height -- height.
  • depth -- bit depth of the pixel.
  • version -- psd file version.




psd_tools.psd.linked_layer

Linked layer structure.

LinkedLayers

List of LinkedLayer structure. See LinkedLayer.

LinkedLayer


psd_tools.psd.patterns

Patterns structure.

Patterns

List of Pattern structure. See Pattern.

Pattern


VirtualMemoryArrayList


VirtualMemoryArray


psd_tools.psd.tagged_blocks

Tagged block data structure.

Todo

Support the following tagged blocks: Tag.PATTERN_DATA, Tag.TYPE_TOOL_INFO, Tag.LAYER, Tag.ALPHA



TaggedBlocks

Dict of tagged block items.

See Tag <#psd_tools.constants.Tag> for available keys.

Example:

from psd_tools.constants import Tag
# Iterate over fields
for key in tagged_blocks:

print(key) # Get a field value = tagged_blocks.get_data(Tag.TYPE_TOOL_OBJECT_SETTING)



TaggedBlock

Layer tagged block with extra info.
4-character code. See Tag <#psd_tools.constants.Tag>

Data.


Annotations


Annotation


Bytes


ChannelBlendingRestrictionsSetting

ChannelBlendingRestrictionsSetting structure.

List of restricted channel numbers (int).


FilterMask


MetadataSettings


MetadataSetting


PixelSourceData2


PlacedLayerData


ProtectedSetting


ReferencePoint


SectionDividerSetting


SheetColorSetting

SheetColorSetting value.

This setting represents color label in the layers panel in Photoshop UI.



SmartObjectLayerData


TypeToolObjectSetting


UserMask


psd_tools.psd.vector

Vector mask, path, and stroke structure.

Path

List-like Path structure. Elements are either PathFillRule, InitialFillRule, ClipboardRecord, ClosedPath, or OpenPath.

Subpath

Subpath element. This is a list of Knot objects.

Note:

There are undocumented data associated with this structure.


int value indicating how multiple subpath should be combined:

1: Or (union), 2: Not-Or, 3: And (intersect), 0: Xor (exclude)

The first path element is applied to the background surface. Intersection does not have strokes.


int index that specifies corresponding origination object.

Returns whether if the path is closed or not.
bool.



Knot

Knot element consisting of 3 control points for Bezier curves.
(y, x) tuple of preceding control point in relative coordinates.

(y, x) tuple of anchor point in relative coordinates.

(y, x) tuple of leaving control point in relative coordinates.


ClipboardRecord

Clipboard record.
Top position in int

Left position in int

Bottom position in int

Right position in int

Resolution in int


PathFillRule

Path fill rule record, empty.

InitialFillRule

Initial fill rule record.
A value of 1 means that the fill starts with all pixels. The value will be either 0 or 1.


VectorMaskSetting

VectorMaskSetting structure.

List of Subpath objects.

Flag to indicate that the vector mask is disabled.

Flag to indicate that the vector mask is inverted.

Flag to indicate that the vector mask is not linked.


VectorStrokeContentSetting


psd_tools.terminology

Constants for descriptor.

This file is automaticaly generated by tools/extract_terminology.py

Klass

Klass definitions extracted from PITerminology.h.

See <https://www.adobe.com/devnet/photoshop/sdk.html>

















BevelEmboss = b'ebbl'





BrightnessContrast = b'BrgC'










ChannelMixer = b'ChnM'







ColorBalance = b'ClrB'









Curves = b'Crvs'









DropShadow = b'DrSh'








Ellipse = b'Elps'















GradientFill = b'Grdf'

GradientMap = b'GdMp'









HalftoneScreen = b'HlfS'







HueSaturation = b'HStr'







InnerGlow = b'IrGl'

InnerShadow = b'IrSh'






Layer = b'Lyr '



Levels = b'Lvls'



Line = b'Ln '




Mask = b'Msk '






Offset = b'Ofst'


OuterGlow = b'OrGl'







Path = b'Path'



Pattern = b'PttR'















Posterize = b'Pstr'



Property = b'Prpr'







Rectangle = b'Rctn'




SelectiveColor = b'SlcC'
















Threshold = b'Thrs'












Enum

Enum definitions extracted from PITerminology.h.

See <https://www.adobe.com/devnet/photoshop/sdk.html>
































































BlackAndWhite = b'BanW'


































































































Ellipse = b'Elps'





































GradientFill = b'GrFl'



























HalftoneScreen = b'HlfS'






































































Line = b'Ln '















Mask = b'Msk '








































































Pattern = b'Ptrn'





























































































































































Threshold = b'Thrh'





















































































_16BitsPerPixel = b'16Bt'

_1BitPerPixel = b'OnBt'

_2BitsPerPixel = b'2Bts'

_32BitsPerPixel = b'32Bt'

_4BitsPerPixel = b'4Bts'

_5000 = b'5000'

_5500 = b'5500'

_6500 = b'6500'

_72Color = b'72Cl'

_72Gray = b'72Gr'

_7500 = b'7500'

_8BitsPerPixel = b'EghB'

_9300 = b'9300'

_None = b'None'


Event

Event definitions extracted from PITerminology.h.

See <https://www.adobe.com/devnet/photoshop/sdk.html>






















ChannelMixer = b'ChnM'






ColorBalance = b'ClrB'

















Curves = b'Crvs'














































GradientMap = b'GrMp'



Group = b'GrpL'



HalftoneScreen = b'HlfS'



HueSaturation = b'HStr'









Levels = b'Lvls'























Offset = b'Ofst'



















Posterize = b'Pstr'






















SelectiveColor = b'SlcC'




















Stroke = b'Strk'








Threshold = b'Thrs'



















_3DTransform = b'TdT '


Form

Form definitions extracted from PITerminology.h.

See <https://www.adobe.com/devnet/photoshop/sdk.html>

Class = b'Clss'

Enumerated = b'Enmr'

Identifier = b'Idnt'

Index = b'indx'

Offset = b'rele'

Property = b'prop'


Key

Key definitions extracted from PITerminology.h.

See <https://www.adobe.com/devnet/photoshop/sdk.html>

















































BevelEmboss = b'ebbl'


















































































Compression = b'Cmpr'














Copyright = b'Cpyr'






















































DropShadow = b'DrSh'






























Exposure = b'Exps'




















































































GradientFill = b'Grdf'




















Group = b'Grup'










HalftoneScreen = b'HlfS'


































InnerGlow = b'IrGl'


InnerShadow = b'IrSh'






















































Layer = b'Lyr '





Layers = b'Lyrs'







Levels = b'Lvls'









Line = b'Line'





































Name = b'Nm '





















Offset = b'Ofst'









OuterGlow = b'OrGl'






















Path = b'Path'



Pattern = b'Pttn'
































































































































































Threshold = b'Thsh'














TransferFunction = b'TrnF'











Type = b'Type'























































_3DAntiAlias = b'Alis'



Type

Type definitions extracted from PITerminology.h.

See <https://www.adobe.com/devnet/photoshop/sdk.html>













BlendMode = b'BlnM'






























































GlobalObject = b'GlbO'






















































RawData = b'tdta'






















UnitFloat = b'UntF'










Unit


INDICES AND TABLES

  • Index <>
  • Module Index <>
  • Search Page <>

Author

Kota Yamaguchi

Copyright

2019, Kota Yamaguchi

November 30, 2025 1.12.0