table of contents
| 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:
Note:
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 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:
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:
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:
- Check the Actions tab <https://github.com/psd-tools/psd-tools/actions> for workflow status
- Verify the release on GitHub <https://github.com/psd-tools/psd-tools/releases>
- Confirm the package is available on PyPI <https://pypi.org/project/psd-tools/>
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¶
- class psd_tools.PSDImage(data: PSD <#psd_tools.psd.PSD>)
- 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()
- append(layer: Layer <#psd_tools.api.layers.Layer>) -> None
- 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.
- Parameters
- layer -- The layer to add.
- Raises
- TypeError -- If the provided object is not a Layer instance.
- ValueError -- If attempting to add a group to itself.
- property bbox: tuple[int, int, int, int]
- 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.
- Returns
- (left, top, right, bottom) tuple.
- clear() -> None
- Clears the group.
This operation rewrites the internal references of the layers.
- Returns
- None
- property color_mode: ColorMode <#psd_tools.constants.ColorMode>
- Document color mode, such as 'RGB' or 'GRAYSCALE'. See ColorMode <#psd_tools.constants.ColorMode>.
- Returns
- ColorMode <#psd_tools.constants.ColorMode>
- property compatibility_mode: CompatibilityMode <#psd_tools.constants.CompatibilityMode>
- 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.
- Returns
- CompatibilityMode <#psd_tools.constants.CompatibilityMode>
- 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().
- Returns
- PIL.Image.
- count(layer: Layer <#psd_tools.api.layers.Layer>) -> int
- Counts the number of occurrences of a layer in the group.
- Parameters
- layer -- The layer to count.
- create_group(layer_list: Iterable[Layer <#psd_tools.api.layers.Layer>] | None = None, name: str = 'Group', opacity: int = 255, blend_mode: BlendMode <#psd_tools.constants.BlendMode> = BlendMode.PASS_THROUGH, open_folder: bool = True) -> Group <#psd_tools.api.layers.Group>
- 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.
- Returns
- The created Group <#psd_tools.api.layers.Group> object.
- create_pixel_layer(image: Image, name: str = 'Layer', top: int = 0, left: int = 0, compression: Compression <#psd_tools.constants.Compression> = Compression.RLE, opacity: int = 255, blend_mode: BlendMode <#psd_tools.constants.BlendMode> = BlendMode.NORMAL) -> PixelLayer <#psd_tools.api.layers.PixelLayer>
- 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.
- Returns
- The created PixelLayer <#psd_tools.api.layers.PixelLayer> object.
- descendants(include_clip: bool = True) -> Iterator[Layer <#psd_tools.api.layers.Layer>]
- Return a generator to iterate over all descendant layers.
- Parameters
- 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)
- extend(layers: Iterable[Layer <#psd_tools.api.layers.Layer>]) -> None
- 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.
- Parameters
- layers -- The layers to add.
- Raises
- TypeError -- If the provided object is not a Layer instance.
- ValueError -- If attempting to add a group to itself.
- find(name: str) -> Layer <#psd_tools.api.layers.Layer> | None
- Returns the first layer found for the given layer name
- Parameters
- name
- findall(name: str) -> Iterator[Layer <#psd_tools.api.layers.Layer>]
- Return a generator to iterate over all layers with the given name.
- Parameters
- name
- classmethod frompil(image: Image, compression: Compression <#psd_tools.constants.Compression> = Compression.RLE) -> Self
- Create a new layer-less PSD document from PIL Image.
- image -- PIL Image object.
- compression -- ImageData compression option. See Compression <#psd_tools.constants.Compression>.
- Returns
- A PSDImage <#psd_tools.api.psd_image.PSDImage> object.
- has_preview() -> bool
- Returns if the document has real merged data. When True, topil() returns pre-composed data.
- has_thumbnail() -> bool
- True if the PSDImage has a thumbnail resource.
- property image_resources: ImageResources <#psd_tools.psd.image_resources.ImageResources>
- 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.
- Returns
- 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)
- index(layer: Layer <#psd_tools.api.layers.Layer>) -> int
- Returns the index of the specified layer in the group.
- Parameters
- layer -- The layer to find.
- insert(index: int, layer: Layer <#psd_tools.api.layers.Layer>) -> None
- 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.
- is_group() -> bool
- Return True if this is a group.
- is_visible() -> bool
- Returns visibility of the element.
- classmethod new(mode: str, size: tuple[int, int], color: int = 0, depth: Literal[8, 16, 32] = 8, **kwargs: Any) -> Self
- 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.
- Returns
- A PSDImage <#psd_tools.api.psd_image.PSDImage> object.
- numpy(channel: Literal['color', 'shape', 'alpha', 'mask'] | None = None) -> ndarray
- Get NumPy array of the layer.
- Parameters
- channel -- Which channel to return, can be 'color', 'shape', 'alpha', or 'mask'. Default is 'color+alpha'.
- Returns
- numpy.ndarray
- classmethod open(fp: BinaryIO | str | bytes | PathLike, **kwargs: Any) -> Self
- 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.
- Returns
- A PSDImage <#psd_tools.api.psd_image.PSDImage> object.
- property parent: None
- Parent of this layer.
- property pil_mode: str
- PIL mode of the document.
- pop(index: int = -1) -> Layer <#psd_tools.api.layers.Layer>
- Removes the specified layer from the list and returns it.
This operation rewrites the internal references of the layer.
- Parameters
- index -- The index of the layer to remove. Default is -1 (the last layer).
- Raises
- IndexError -- If the index is out of range.
- Returns
- The removed layer.
- remove(layer: Layer <#psd_tools.api.layers.Layer>) -> Self
- Removes the specified layer from the group.
This operation rewrites the internal references of the layer.
- Parameters
- layer -- The layer to remove.
- Raises
- ValueError -- If the layer is not found in the group.
- Returns
- self
- save(fp: BinaryIO | str | bytes | PathLike, mode: str = 'wb', **kwargs: Any) -> None
- 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'.
- property tagged_blocks: TaggedBlocks <#psd_tools.psd.tagged_blocks.TaggedBlocks> | None
- Document tagged blocks that is a dict-like container of settings.
See psd_tools.constants.Tag <#psd_tools.constants.Tag> for available keys.
- Returns
- TaggedBlocks <#psd_tools.psd.tagged_blocks.TaggedBlocks> or None.
Example:
from psd_tools.constants import Tag patterns = psd.tagged_blocks.get_data(Tag.PATTERNS1)
- thumbnail() -> Image | None
- Returns a thumbnail image in PIL.Image. When the file does not contain an embedded thumbnail image, returns None.
- topil(channel: int | ChannelID <#psd_tools.constants.ChannelID> | None = None, apply_icc: bool = True) -> Image | None
- 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.
- Returns
- PIL.Image, or None if the composed image is not available.
- property viewbox: tuple[int, int, int, int]
- Return bounding box of the viewport.
- Returns
- (left, top, right, bottom) tuple.
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¶
- class psd_tools.api.psd_image.PSDImage(data: PSD <#psd_tools.psd.PSD>)
- 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()
- append(layer: Layer <#psd_tools.api.layers.Layer>) -> None
- 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.
- Parameters
- layer -- The layer to add.
- Raises
- TypeError -- If the provided object is not a Layer instance.
- ValueError -- If attempting to add a group to itself.
- property bbox: tuple[int, int, int, int]
- 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.
- Returns
- (left, top, right, bottom) tuple.
- clear() -> None
- Clears the group.
This operation rewrites the internal references of the layers.
- Returns
- None
- property color_mode: ColorMode <#psd_tools.constants.ColorMode>
- Document color mode, such as 'RGB' or 'GRAYSCALE'. See ColorMode <#psd_tools.constants.ColorMode>.
- Returns
- ColorMode <#psd_tools.constants.ColorMode>
- property compatibility_mode: CompatibilityMode <#psd_tools.constants.CompatibilityMode>
- 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.
- Returns
- CompatibilityMode <#psd_tools.constants.CompatibilityMode>
- 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().
- Returns
- PIL.Image.
- count(layer: Layer <#psd_tools.api.layers.Layer>) -> int
- Counts the number of occurrences of a layer in the group.
- Parameters
- layer -- The layer to count.
- create_group(layer_list: Iterable[Layer <#psd_tools.api.layers.Layer>] | None = None, name: str = 'Group', opacity: int = 255, blend_mode: BlendMode <#psd_tools.constants.BlendMode> = BlendMode.PASS_THROUGH, open_folder: bool = True) -> Group <#psd_tools.api.layers.Group>
- 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.
- Returns
- The created Group <#psd_tools.api.layers.Group> object.
- create_pixel_layer(image: Image, name: str = 'Layer', top: int = 0, left: int = 0, compression: Compression <#psd_tools.constants.Compression> = Compression.RLE, opacity: int = 255, blend_mode: BlendMode <#psd_tools.constants.BlendMode> = BlendMode.NORMAL) -> PixelLayer <#psd_tools.api.layers.PixelLayer>
- 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.
- Returns
- The created PixelLayer <#psd_tools.api.layers.PixelLayer> object.
- descendants(include_clip: bool = True) -> Iterator[Layer <#psd_tools.api.layers.Layer>]
- Return a generator to iterate over all descendant layers.
- Parameters
- 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)
- extend(layers: Iterable[Layer <#psd_tools.api.layers.Layer>]) -> None
- 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.
- Parameters
- layers -- The layers to add.
- Raises
- TypeError -- If the provided object is not a Layer instance.
- ValueError -- If attempting to add a group to itself.
- find(name: str) -> Layer <#psd_tools.api.layers.Layer> | None
- Returns the first layer found for the given layer name
- Parameters
- name
- findall(name: str) -> Iterator[Layer <#psd_tools.api.layers.Layer>]
- Return a generator to iterate over all layers with the given name.
- Parameters
- name
- classmethod frompil(image: Image, compression: Compression <#psd_tools.constants.Compression> = Compression.RLE) -> Self
- Create a new layer-less PSD document from PIL Image.
- image -- PIL Image object.
- compression -- ImageData compression option. See Compression <#psd_tools.constants.Compression>.
- Returns
- A PSDImage object.
- has_preview() -> bool
- Returns if the document has real merged data. When True, topil() returns pre-composed data.
- has_thumbnail() -> bool
- True if the PSDImage has a thumbnail resource.
- property image_resources: ImageResources <#psd_tools.psd.image_resources.ImageResources>
- 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.
- Returns
- 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)
- index(layer: Layer <#psd_tools.api.layers.Layer>) -> int
- Returns the index of the specified layer in the group.
- Parameters
- layer -- The layer to find.
- insert(index: int, layer: Layer <#psd_tools.api.layers.Layer>) -> None
- 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.
- is_group() -> bool
- Return True if this is a group.
- is_visible() -> bool
- Returns visibility of the element.
- classmethod new(mode: str, size: tuple[int, int], color: int = 0, depth: Literal[8, 16, 32] = 8, **kwargs: Any) -> Self
- 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.
- Returns
- A PSDImage object.
- numpy(channel: Literal['color', 'shape', 'alpha', 'mask'] | None = None) -> ndarray
- Get NumPy array of the layer.
- Parameters
- channel -- Which channel to return, can be 'color', 'shape', 'alpha', or 'mask'. Default is 'color+alpha'.
- Returns
- numpy.ndarray
- classmethod open(fp: BinaryIO | str | bytes | PathLike, **kwargs: Any) -> Self
- 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.
- Returns
- A PSDImage object.
- property parent: None
- Parent of this layer.
- property pil_mode: str
- PIL mode of the document.
- pop(index: int = -1) -> Layer <#psd_tools.api.layers.Layer>
- Removes the specified layer from the list and returns it.
This operation rewrites the internal references of the layer.
- Parameters
- index -- The index of the layer to remove. Default is -1 (the last layer).
- Raises
- IndexError -- If the index is out of range.
- Returns
- The removed layer.
- remove(layer: Layer <#psd_tools.api.layers.Layer>) -> Self
- Removes the specified layer from the group.
This operation rewrites the internal references of the layer.
- Parameters
- layer -- The layer to remove.
- Raises
- ValueError -- If the layer is not found in the group.
- Returns
- self
- save(fp: BinaryIO | str | bytes | PathLike, mode: str = 'wb', **kwargs: Any) -> None
- 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'.
- property tagged_blocks: TaggedBlocks <#psd_tools.psd.tagged_blocks.TaggedBlocks> | None
- Document tagged blocks that is a dict-like container of settings.
See psd_tools.constants.Tag <#psd_tools.constants.Tag> for available keys.
- Returns
- TaggedBlocks <#psd_tools.psd.tagged_blocks.TaggedBlocks> or None.
Example:
from psd_tools.constants import Tag patterns = psd.tagged_blocks.get_data(Tag.PATTERNS1)
- thumbnail() -> Image | None
- Returns a thumbnail image in PIL.Image. When the file does not contain an embedded thumbnail image, returns None.
- topil(channel: int | ChannelID <#psd_tools.constants.ChannelID> | None = None, apply_icc: bool = True) -> Image | None
- 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.
- Returns
- PIL.Image, or None if the composed image is not available.
- property viewbox: tuple[int, int, int, int]
- Return bounding box of the viewport.
- Returns
- (left, top, right, bottom) tuple.
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¶
- class psd_tools.api.adjustments.SolidColorFill(*args: Any)
- Solid color fill.
- property bbox: tuple[int, int, int, int]
- (left, top, right, bottom) tuple.
- property blend_mode: BlendMode <#psd_tools.constants.BlendMode>
- Blend mode of this layer. Writable.
Example:
from psd_tools.constants import BlendMode if layer.blend_mode == BlendMode.NORMAL:
layer.blend_mode = BlendMode.SCREEN
- Returns
- BlendMode <#psd_tools.constants.BlendMode>.
- property clipping_layer: bool
- Deprecated. Use clipping property instead.
- composite(viewport: tuple[int, int, int, int] | None = None, force: bool = False, color: float | tuple[float, ...] | ndarray = 1.0, alpha: float | ndarray = 0.0, layer_filter: Callable | None = None, apply_icc: bool = True) -> Image | None
- 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().
- Returns
- PIL.Image.Image or None.
- property data: DescriptorBlock
- Color in Descriptor(RGB).
- delete_layer() -> Self
- Deprecated: Use layer.parent.remove(layer) instead.
- property effects: Effects <#psd_tools.api.effects.Effects>
- Layer effects.
- Returns
- Effects <#psd_tools.api.effects.Effects>
- has_clip_layers(visible: bool = False) -> bool
- Returns True if the layer has associated clipping.
- Parameters
- visible -- If True, check for visible clipping layers.
- Returns
- bool
- has_effects(enabled: bool = True, name: str | None = None) -> bool
- Returns True if the layer has effects.
- enabled -- If True, check for enabled effects.
- name -- If given, check for specific effect type.
- Returns
- bool
- has_pixels() -> bool
- Returns True if the layer has associated pixels. When this is True, topil method returns PIL.Image.Image.
- Returns
- bool
- has_stroke() -> bool
- Returns True if the shape has a stroke.
- property kind: str
- Kind of this layer, such as group, pixel, shape, type, smartobject, or psdimage. Class name without layer suffix.
- Returns
- str
- lock(lock_flags: int = ProtectedFlags.COMPLETE) -> None
- Locks a layer accordind to the combination of flags.
- Parameters
- 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)
- property mask: Mask <#psd_tools.api.mask.Mask> | None
- Returns mask associated with this layer.
- Returns
- Mask <#psd_tools.api.mask.Mask> or None
- move_down(offset: int = 1) -> Self
- Moves the layer down a certain offset within the group the layer is in.
- Parameters
- offset -- The number of positions to move the layer down (can be negative).
- Raises
- ValueError -- If layer has no parent or parent is not a group
- IndexError -- If the new index is out of bounds
- Returns
- self
- move_to_group(group: GroupMixin) -> Self
- Deprecated: Use group.append(layer) instead.
- Parameters
- group -- The group the current layer will be moved into.
- move_up(offset: int = 1) -> Self
- Moves the layer up a certain offset within the group the layer is in.
- Parameters
- offset -- The number of positions to move the layer up (can be negative).
- Raises
- ValueError -- If layer has no parent or parent is not a group
- IndexError -- If the new index is out of bounds
- Returns
- self
- next_sibling(visible: bool = False) -> Self | None
- Next sibling of this layer.
- numpy(channel: str | None = None, real_mask: bool = True) -> ndarray | None
- Get NumPy array of the layer.
- Parameters
- channel -- Which channel to return, can be 'color', 'shape', 'alpha', or 'mask'. Default is 'color+alpha'.
- Returns
- numpy.ndarray or None if there is no pixel.
- property origination: list[Origination]
- 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>.
- Returns
- 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>.
- property parent: GroupMixinProtocol | None
- Parent of this layer.
- previous_sibling(visible: bool = False) -> Self | None
- Previous sibling of this layer.
- property reference_point: tuple[float, float]
- 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.
- Returns
- (x, y) tuple
- property stroke: Stroke <#psd_tools.api.shape.Stroke> | None
- Property for strokes.
- property tagged_blocks: TaggedBlocks <#psd_tools.psd.tagged_blocks.TaggedBlocks>
- Layer tagged blocks that is a dict-like container of settings.
See psd_tools.constants.Tag <#psd_tools.constants.Tag> for available keys.
- Returns
- TaggedBlocks <#psd_tools.psd.tagged_blocks.TaggedBlocks>.
Example:
from psd_tools.constants import Tag metadata = layer.tagged_blocks.get_data(Tag.METADATA_SETTING)
- topil(channel: int | None = None, apply_icc: bool = True) -> Image | None
- 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.
- Returns
- 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:
- property vector_mask: VectorMask <#psd_tools.api.shape.VectorMask> | None
- Returns vector mask associated with this layer.
- Returns
- VectorMask <#psd_tools.api.shape.VectorMask> or None
- property visible: bool
- Layer visibility. Doesn't take group visibility in account. Writable.
- Returns
- bool
PatternFill¶
- class psd_tools.api.adjustments.PatternFill(*args: Any)
- Pattern fill.
- property bbox: tuple[int, int, int, int]
- (left, top, right, bottom) tuple.
- property blend_mode: BlendMode <#psd_tools.constants.BlendMode>
- Blend mode of this layer. Writable.
Example:
from psd_tools.constants import BlendMode if layer.blend_mode == BlendMode.NORMAL:
layer.blend_mode = BlendMode.SCREEN
- Returns
- BlendMode <#psd_tools.constants.BlendMode>.
- property clipping_layer: bool
- Deprecated. Use clipping property instead.
- composite(viewport: tuple[int, int, int, int] | None = None, force: bool = False, color: float | tuple[float, ...] | ndarray = 1.0, alpha: float | ndarray = 0.0, layer_filter: Callable | None = None, apply_icc: bool = True) -> Image | None
- 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().
- Returns
- PIL.Image.Image or None.
- property data: DescriptorBlock
- Pattern in Descriptor(PATTERN).
- delete_layer() -> Self
- Deprecated: Use layer.parent.remove(layer) instead.
- property effects: Effects <#psd_tools.api.effects.Effects>
- Layer effects.
- Returns
- Effects <#psd_tools.api.effects.Effects>
- has_clip_layers(visible: bool = False) -> bool
- Returns True if the layer has associated clipping.
- Parameters
- visible -- If True, check for visible clipping layers.
- Returns
- bool
- has_effects(enabled: bool = True, name: str | None = None) -> bool
- Returns True if the layer has effects.
- enabled -- If True, check for enabled effects.
- name -- If given, check for specific effect type.
- Returns
- bool
- has_pixels() -> bool
- Returns True if the layer has associated pixels. When this is True, topil method returns PIL.Image.Image.
- Returns
- bool
- has_stroke() -> bool
- Returns True if the shape has a stroke.
- property kind: str
- Kind of this layer, such as group, pixel, shape, type, smartobject, or psdimage. Class name without layer suffix.
- Returns
- str
- lock(lock_flags: int = ProtectedFlags.COMPLETE) -> None
- Locks a layer accordind to the combination of flags.
- Parameters
- 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)
- property mask: Mask <#psd_tools.api.mask.Mask> | None
- Returns mask associated with this layer.
- Returns
- Mask <#psd_tools.api.mask.Mask> or None
- move_down(offset: int = 1) -> Self
- Moves the layer down a certain offset within the group the layer is in.
- Parameters
- offset -- The number of positions to move the layer down (can be negative).
- Raises
- ValueError -- If layer has no parent or parent is not a group
- IndexError -- If the new index is out of bounds
- Returns
- self
- move_to_group(group: GroupMixin) -> Self
- Deprecated: Use group.append(layer) instead.
- Parameters
- group -- The group the current layer will be moved into.
- move_up(offset: int = 1) -> Self
- Moves the layer up a certain offset within the group the layer is in.
- Parameters
- offset -- The number of positions to move the layer up (can be negative).
- Raises
- ValueError -- If layer has no parent or parent is not a group
- IndexError -- If the new index is out of bounds
- Returns
- self
- next_sibling(visible: bool = False) -> Self | None
- Next sibling of this layer.
- numpy(channel: str | None = None, real_mask: bool = True) -> ndarray | None
- Get NumPy array of the layer.
- Parameters
- channel -- Which channel to return, can be 'color', 'shape', 'alpha', or 'mask'. Default is 'color+alpha'.
- Returns
- numpy.ndarray or None if there is no pixel.
- property origination: list[Origination]
- 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>.
- Returns
- 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>.
- property parent: GroupMixinProtocol | None
- Parent of this layer.
- previous_sibling(visible: bool = False) -> Self | None
- Previous sibling of this layer.
- property reference_point: tuple[float, float]
- 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.
- Returns
- (x, y) tuple
- property stroke: Stroke <#psd_tools.api.shape.Stroke> | None
- Property for strokes.
- property tagged_blocks: TaggedBlocks <#psd_tools.psd.tagged_blocks.TaggedBlocks>
- Layer tagged blocks that is a dict-like container of settings.
See psd_tools.constants.Tag <#psd_tools.constants.Tag> for available keys.
- Returns
- TaggedBlocks <#psd_tools.psd.tagged_blocks.TaggedBlocks>.
Example:
from psd_tools.constants import Tag metadata = layer.tagged_blocks.get_data(Tag.METADATA_SETTING)
- topil(channel: int | None = None, apply_icc: bool = True) -> Image | None
- 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.
- Returns
- 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:
- property vector_mask: VectorMask <#psd_tools.api.shape.VectorMask> | None
- Returns vector mask associated with this layer.
- Returns
- VectorMask <#psd_tools.api.shape.VectorMask> or None
- property visible: bool
- Layer visibility. Doesn't take group visibility in account. Writable.
- Returns
- bool
GradientFill¶
- class psd_tools.api.adjustments.GradientFill(*args: Any)
- Gradient fill.
- property bbox: tuple[int, int, int, int]
- (left, top, right, bottom) tuple.
- property blend_mode: BlendMode <#psd_tools.constants.BlendMode>
- Blend mode of this layer. Writable.
Example:
from psd_tools.constants import BlendMode if layer.blend_mode == BlendMode.NORMAL:
layer.blend_mode = BlendMode.SCREEN
- Returns
- BlendMode <#psd_tools.constants.BlendMode>.
- property clipping_layer: bool
- Deprecated. Use clipping property instead.
- composite(viewport: tuple[int, int, int, int] | None = None, force: bool = False, color: float | tuple[float, ...] | ndarray = 1.0, alpha: float | ndarray = 0.0, layer_filter: Callable | None = None, apply_icc: bool = True) -> Image | None
- 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().
- Returns
- PIL.Image.Image or None.
- property data: DescriptorBlock
- Gradient in Descriptor(GRADIENT).
- delete_layer() -> Self
- Deprecated: Use layer.parent.remove(layer) instead.
- property effects: Effects <#psd_tools.api.effects.Effects>
- Layer effects.
- Returns
- Effects <#psd_tools.api.effects.Effects>
- property gradient_kind: str
- Kind of the gradient, one of the following:
- Linear
- Radial
- Angle
- Reflected
- Diamond
- has_clip_layers(visible: bool = False) -> bool
- Returns True if the layer has associated clipping.
- Parameters
- visible -- If True, check for visible clipping layers.
- Returns
- bool
- has_effects(enabled: bool = True, name: str | None = None) -> bool
- Returns True if the layer has effects.
- enabled -- If True, check for enabled effects.
- name -- If given, check for specific effect type.
- Returns
- bool
- has_pixels() -> bool
- Returns True if the layer has associated pixels. When this is True, topil method returns PIL.Image.Image.
- Returns
- bool
- has_stroke() -> bool
- Returns True if the shape has a stroke.
- property kind: str
- Kind of this layer, such as group, pixel, shape, type, smartobject, or psdimage. Class name without layer suffix.
- Returns
- str
- lock(lock_flags: int = ProtectedFlags.COMPLETE) -> None
- Locks a layer accordind to the combination of flags.
- Parameters
- 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)
- property mask: Mask <#psd_tools.api.mask.Mask> | None
- Returns mask associated with this layer.
- Returns
- Mask <#psd_tools.api.mask.Mask> or None
- move_down(offset: int = 1) -> Self
- Moves the layer down a certain offset within the group the layer is in.
- Parameters
- offset -- The number of positions to move the layer down (can be negative).
- Raises
- ValueError -- If layer has no parent or parent is not a group
- IndexError -- If the new index is out of bounds
- Returns
- self
- move_to_group(group: GroupMixin) -> Self
- Deprecated: Use group.append(layer) instead.
- Parameters
- group -- The group the current layer will be moved into.
- move_up(offset: int = 1) -> Self
- Moves the layer up a certain offset within the group the layer is in.
- Parameters
- offset -- The number of positions to move the layer up (can be negative).
- Raises
- ValueError -- If layer has no parent or parent is not a group
- IndexError -- If the new index is out of bounds
- Returns
- self
- next_sibling(visible: bool = False) -> Self | None
- Next sibling of this layer.
- numpy(channel: str | None = None, real_mask: bool = True) -> ndarray | None
- Get NumPy array of the layer.
- Parameters
- channel -- Which channel to return, can be 'color', 'shape', 'alpha', or 'mask'. Default is 'color+alpha'.
- Returns
- numpy.ndarray or None if there is no pixel.
- property origination: list[Origination]
- 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>.
- Returns
- 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>.
- property parent: GroupMixinProtocol | None
- Parent of this layer.
- previous_sibling(visible: bool = False) -> Self | None
- Previous sibling of this layer.
- property reference_point: tuple[float, float]
- 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.
- Returns
- (x, y) tuple
- property stroke: Stroke <#psd_tools.api.shape.Stroke> | None
- Property for strokes.
- property tagged_blocks: TaggedBlocks <#psd_tools.psd.tagged_blocks.TaggedBlocks>
- Layer tagged blocks that is a dict-like container of settings.
See psd_tools.constants.Tag <#psd_tools.constants.Tag> for available keys.
- Returns
- TaggedBlocks <#psd_tools.psd.tagged_blocks.TaggedBlocks>.
Example:
from psd_tools.constants import Tag metadata = layer.tagged_blocks.get_data(Tag.METADATA_SETTING)
- topil(channel: int | None = None, apply_icc: bool = True) -> Image | None
- 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.
- Returns
- 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:
- property vector_mask: VectorMask <#psd_tools.api.shape.VectorMask> | None
- Returns vector mask associated with this layer.
- Returns
- VectorMask <#psd_tools.api.shape.VectorMask> or None
- property visible: bool
- Layer visibility. Doesn't take group visibility in account. Writable.
- Returns
- bool
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¶
- class psd_tools.api.adjustments.Levels(*args: Any)
- Levels adjustment.
Levels contain a list of LevelRecord.
- property master: LevelRecord
- Master record.
Vibrance¶
HueSaturation¶
- class psd_tools.api.adjustments.HueSaturation(*args: Any)
- Hue/Saturation adjustment.
HueSaturation contains a list of data.
ColorBalance¶
BlackAndWhite¶
PhotoFilter¶
ChannelMixer¶
ColorLookup¶
- class psd_tools.api.adjustments.ColorLookup(*args: Any)
- Color lookup adjustment.
Posterize¶
- class psd_tools.api.adjustments.Posterize(*args: Any)
- Posterize adjustment.
Threshold¶
- class psd_tools.api.adjustments.Threshold(*args: Any)
- Threshold adjustment.
SelectiveColor¶
GradientMap¶
- class psd_tools.api.adjustments.GradientMap(*args: Any)
- Gradient map adjustment.
- property interpolation: float
- Interpolation between 0.0 and 1.0.
psd_tools.api.effects¶
Effects module.
- class psd_tools.api.effects.Effects(layer: LayerProtocol)
- List-like effects.
Only present effects are kept.
- find(name: str, enabled: bool = True) -> Iterator[_Effect]
- 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.
- Return type
- Iterator[Effect]
- property scale: float
- Scale value.
DropShadow¶
- property angle: float
- Angle value.
- property anti_aliased: bool
- Angi-aliased.
- property blend_mode: bytes
- Effect blending mode.
- property choke: float
- Choke level in pixels.
- property contour: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Contour configuration.
- property distance: float
- Distance in pixels.
- property enabled: bool
- Whether if the effect is enabled.
- property layer_knocks_out: bool
- Layers are knocking out.
- property name: str
- Effect name.
- property noise: float
- Noise level in percent.
- property opacity: float
- Layer effect opacity in percentage.
- property present: bool
- Whether if the effect is present in Photoshop UI.
- property shown: bool
- Whether if the effect is shown in dialog.
- property size: float
- Size in pixels.
- property use_global_light: bool
- Using global light.
- property value: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Deprecated
Effect descriptor value. Use descriptor property instead.
InnerShadow¶
- property angle: float
- Angle value.
- property anti_aliased: bool
- Angi-aliased.
- property blend_mode: bytes
- Effect blending mode.
- property choke: float
- Choke level in pixels.
- property contour: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Contour configuration.
- property distance: float
- Distance in pixels.
- property enabled: bool
- Whether if the effect is enabled.
- property name: str
- Effect name.
- property noise: float
- Noise level in percent.
- property opacity: float
- Layer effect opacity in percentage.
- property present: bool
- Whether if the effect is present in Photoshop UI.
- property shown: bool
- Whether if the effect is shown in dialog.
- property size: float
- Size in pixels.
- property use_global_light: bool
- Using global light.
- property value: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Deprecated
Effect descriptor value. Use descriptor property instead.
OuterGlow¶
- property angle: float
- Angle value.
- property anti_aliased: bool
- Angi-aliased.
- property blend_mode: bytes
- Effect blending mode.
- property choke: float
- Choke level in pixels.
- property contour: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Contour configuration.
- property dithered: bool
- Dither flag.
- property enabled: bool
- Whether if the effect is enabled.
- property glow_type: bytes
- Glow type.
- property gradient: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Gradient configuration.
- property name: str
- Effect name.
- property noise: float
- Noise level in percent.
- property offset: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Offset value in Pnt descriptor.
- property opacity: float
- Layer effect opacity in percentage.
- property present: bool
- Whether if the effect is present in Photoshop UI.
- property quality_jitter: float
- Quality jitter in percent.
- property quality_range: float
- Quality range in percent.
- property reversed: bool
- Reverse flag.
- property shown: bool
- Whether if the effect is shown in dialog.
- property size: float
- Size in pixels.
- property spread: float
- Spread level in percent.
- property type: bytes
- Gradient type, one of linear, radial, angle, reflected, or diamond.
- property value: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Deprecated
Effect descriptor value. Use descriptor property instead.
InnerGlow¶
- property angle: float
- Angle value.
- property anti_aliased: bool
- Angi-aliased.
- property blend_mode: bytes
- Effect blending mode.
- property choke: float
- Choke level in pixels.
- property contour: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Contour configuration.
- property dithered: bool
- Dither flag.
- property enabled: bool
- Whether if the effect is enabled.
- property glow_source: bytes
- Elements source.
- property glow_type: bytes
- Glow type.
- property gradient: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Gradient configuration.
- property name: str
- Effect name.
- property noise: float
- Noise level in percent.
- property offset: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Offset value in Pnt descriptor.
- property opacity: float
- Layer effect opacity in percentage.
- property present: bool
- Whether if the effect is present in Photoshop UI.
- property quality_jitter: float
- Quality jitter in percent.
- property quality_range: float
- Quality range in percent.
- property reversed: bool
- Reverse flag.
- property shown: bool
- Whether if the effect is shown in dialog.
- property size: float
- Size in pixels.
- property type: bytes
- Gradient type, one of linear, radial, angle, reflected, or diamond.
- property value: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Deprecated
Effect descriptor value. Use descriptor property instead.
ColorOverlay¶
- property blend_mode: bytes
- Effect blending mode.
- property enabled: bool
- Whether if the effect is enabled.
- property name: str
- Effect name.
- property opacity: float
- Layer effect opacity in percentage.
- property present: bool
- Whether if the effect is present in Photoshop UI.
- property shown: bool
- Whether if the effect is shown in dialog.
- property value: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Deprecated
Effect descriptor value. Use descriptor property instead.
GradientOverlay¶
- property aligned: bool
- Aligned.
- property angle: float
- Angle value.
- property blend_mode: bytes
- Effect blending mode.
- property dithered: bool
- Dither flag.
- property enabled: bool
- Whether if the effect is enabled.
- property gradient: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Gradient configuration.
- property name: str
- Effect name.
- property offset: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Offset value in Pnt descriptor.
- property opacity: float
- Layer effect opacity in percentage.
- property present: bool
- Whether if the effect is present in Photoshop UI.
- property reversed: bool
- Reverse flag.
- property scale: float
- Scale value.
- property shown: bool
- Whether if the effect is shown in dialog.
- property type: bytes
- Gradient type, one of linear, radial, angle, reflected, or diamond.
- property value: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Deprecated
Effect descriptor value. Use descriptor property instead.
PatternOverlay¶
- property aligned: bool
- Aligned.
- property angle: float
- Angle value.
- property blend_mode: bytes
- Effect blending mode.
- property enabled: bool
- Whether if the effect is enabled.
- property linked: bool
- Linked.
- property name: str
- Effect name.
- property opacity: float
- Layer effect opacity in percentage.
- property phase: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Phase value in Point.
- property present: bool
- Whether if the effect is present in Photoshop UI.
- property scale: float
- Scale value.
- property shown: bool
- Whether if the effect is shown in dialog.
- property value: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Deprecated
Effect descriptor value. Use descriptor property instead.
Stroke¶
- property angle: float
- Angle value.
- property blend_mode: bytes
- Effect blending mode.
- property dithered: bool
- Dither flag.
- property enabled: bool
- Whether if the effect is enabled.
- property fill_type: bytes
- Fill type, SolidColor, Gradient, or Pattern.
- property gradient: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Gradient configuration.
- property linked: bool
- Linked.
- property name: str
- Effect name.
- property offset: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Offset value in Pnt descriptor.
- property opacity: float
- Layer effect opacity in percentage.
- property overprint: bool
- Overprint flag.
- property phase: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Phase value in Point.
- property position: bytes
- Position of the stroke, InsetFrame, OutsetFrame, or CenteredFrame.
- property present: bool
- Whether if the effect is present in Photoshop UI.
- property reversed: bool
- Reverse flag.
- property shown: bool
- Whether if the effect is shown in dialog.
- property size: float
- Size value.
- property type: bytes
- Gradient type, one of linear, radial, angle, reflected, or diamond.
- property value: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Deprecated
Effect descriptor value. Use descriptor property instead.
BevelEmboss¶
- property altitude: float
- Altitude value in angle.
- property angle: float
- Angle value.
- property anti_aliased: bool
- Anti-aliased.
- property bevel_style: bytes
- Bevel style, one of OuterBevel, InnerBevel, Emboss, PillowEmboss, or StrokeEmboss.
- property bevel_type: bytes
- Bevel type, one of SoftMatte, HardLight, SoftLight.
- property contour: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Contour configuration.
- property depth: float
- Depth value in percentage.
- property direction: bytes
- Direction, either StampIn or StampOut.
- property enabled: bool
- Whether if the effect is enabled.
- property highlight_color: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Highlight color value.
- property highlight_mode: bytes
- Highlight blending mode.
- property highlight_opacity: float
- Highlight opacity value in percentage.
- property name: str
- Effect name.
- property opacity: float
- Layer effect opacity in percentage.
- property present: bool
- Whether if the effect is present in Photoshop UI.
- property shadow_color: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Shadow color value.
- property shadow_mode: bytes
- Shadow blending mode.
- property shadow_opacity: float
- Shadow opacity value in percentage.
- property shown: bool
- Whether if the effect is shown in dialog.
- property size: float
- Size value in pixel.
- property soften: float
- Soften value in pixels.
- property use_global_light: bool
- Using global light.
- property use_shape: bool
- Using shape.
- property use_texture: bool
- Using texture.
- property value: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Deprecated
Effect descriptor value. Use descriptor property instead.
Satin¶
- property angle: float
- Angle value in degrees.
- property anti_aliased: bool
- Anti-aliased.
- property blend_mode: bytes
- Effect blending mode.
- property contour: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Contour configuration.
- property distance: float
- Distance value in pixels.
- property enabled: bool
- Whether if the effect is enabled.
- property inverted: bool
- Inverted.
- property name: str
- Effect name.
- property opacity: float
- Layer effect opacity in percentage.
- property present: bool
- Whether if the effect is present in Photoshop UI.
- property shown: bool
- Whether if the effect is shown in dialog.
- property size: float
- Size value in pixel.
- property value: Descriptor <#psd_tools.psd.descriptor.Descriptor>
- 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¶
- property bbox: tuple[int, int, int, int]
- (left, top, right, bottom) tuple.
- property blend_mode: BlendMode <#psd_tools.constants.BlendMode>
- Blend mode of this layer. Writable.
Example:
from psd_tools.constants import BlendMode if layer.blend_mode == BlendMode.NORMAL:
layer.blend_mode = BlendMode.SCREEN
- Returns
- BlendMode <#psd_tools.constants.BlendMode>.
- property clipping_layer: bool
- Deprecated. Use clipping property instead.
- composite(viewport: tuple[int, int, int, int] | None = None, force: bool = False, color: float | tuple[float, ...] | ndarray = 1.0, alpha: float | ndarray = 0.0, layer_filter: Callable | None = None, apply_icc: bool = True) -> Image | None
- 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().
- Returns
- PIL.Image.Image or None.
- delete_layer() -> Self
- Deprecated: Use layer.parent.remove(layer) instead.
- property effects: Effects <#psd_tools.api.effects.Effects>
- Layer effects.
- Returns
- Effects <#psd_tools.api.effects.Effects>
- has_clip_layers(visible: bool = False) -> bool
- Returns True if the layer has associated clipping.
- Parameters
- visible -- If True, check for visible clipping layers.
- Returns
- bool
- has_effects(enabled: bool = True, name: str | None = None) -> bool
- Returns True if the layer has effects.
- enabled -- If True, check for enabled effects.
- name -- If given, check for specific effect type.
- Returns
- bool
- has_pixels() -> bool
- Returns True if the layer has associated pixels. When this is True, topil method returns PIL.Image.Image.
- Returns
- bool
- has_stroke() -> bool
- Returns True if the shape has a stroke.
- property kind: str
- Kind of this layer, such as group, pixel, shape, type, smartobject, or psdimage. Class name without layer suffix.
- Returns
- str
- lock(lock_flags: int = ProtectedFlags.COMPLETE) -> None
- Locks a layer accordind to the combination of flags.
- Parameters
- 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)
- property mask: Mask <#psd_tools.api.mask.Mask> | None
- Returns mask associated with this layer.
- Returns
- Mask <#psd_tools.api.mask.Mask> or None
- move_down(offset: int = 1) -> Self
- Moves the layer down a certain offset within the group the layer is in.
- Parameters
- offset -- The number of positions to move the layer down (can be negative).
- Raises
- ValueError -- If layer has no parent or parent is not a group
- IndexError -- If the new index is out of bounds
- Returns
- self
- move_to_group(group: GroupMixin) -> Self
- Deprecated: Use group.append(layer) instead.
- Parameters
- group -- The group the current layer will be moved into.
- move_up(offset: int = 1) -> Self
- Moves the layer up a certain offset within the group the layer is in.
- Parameters
- offset -- The number of positions to move the layer up (can be negative).
- Raises
- ValueError -- If layer has no parent or parent is not a group
- IndexError -- If the new index is out of bounds
- Returns
- self
- next_sibling(visible: bool = False) -> Self | None
- Next sibling of this layer.
- numpy(channel: str | None = None, real_mask: bool = True) -> ndarray | None
- Get NumPy array of the layer.
- Parameters
- channel -- Which channel to return, can be 'color', 'shape', 'alpha', or 'mask'. Default is 'color+alpha'.
- Returns
- numpy.ndarray or None if there is no pixel.
- property origination: list[Origination]
- 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>.
- Returns
- 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>.
- property parent: GroupMixinProtocol | None
- Parent of this layer.
- previous_sibling(visible: bool = False) -> Self | None
- Previous sibling of this layer.
- property reference_point: tuple[float, float]
- 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.
- Returns
- (x, y) tuple
- property stroke: Stroke <#psd_tools.api.shape.Stroke> | None
- Property for strokes.
- property tagged_blocks: TaggedBlocks <#psd_tools.psd.tagged_blocks.TaggedBlocks>
- Layer tagged blocks that is a dict-like container of settings.
See psd_tools.constants.Tag <#psd_tools.constants.Tag> for available keys.
- Returns
- TaggedBlocks <#psd_tools.psd.tagged_blocks.TaggedBlocks>.
Example:
from psd_tools.constants import Tag metadata = layer.tagged_blocks.get_data(Tag.METADATA_SETTING)
- topil(channel: int | None = None, apply_icc: bool = True) -> Image | None
- 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.
- Returns
- 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:
- property vector_mask: VectorMask <#psd_tools.api.shape.VectorMask> | None
- Returns vector mask associated with this layer.
- Returns
- VectorMask <#psd_tools.api.shape.VectorMask> or None
- property visible: bool
- Layer visibility. Doesn't take group visibility in account. Writable.
- Returns
- bool
Artboard¶
- class psd_tools.api.layers.Artboard(parent: GroupMixin, record: LayerRecord <#psd_tools.psd.layer_and_mask.LayerRecord>, channels: ChannelDataList <#psd_tools.psd.layer_and_mask.ChannelDataList>)
- Artboard is a special kind of group that has a pre-defined viewbox.
- property bbox: tuple[int, int, int, int]
- (left, top, right, bottom) tuple.
- property bottom: int
- Bottom coordinate (computed from children, read-only).
- property left: int
- Left coordinate (computed from children, read-only).
- property right: int
- Right coordinate (computed from children, read-only).
- property top: int
- Top coordinate (computed from children, read-only).
Group¶
- class psd_tools.api.layers.Group(parent: GroupMixin, record: LayerRecord <#psd_tools.psd.layer_and_mask.LayerRecord>, channels: ChannelDataList <#psd_tools.psd.layer_and_mask.ChannelDataList>)
- Group of layers.
Example:
group = psd[1] for layer in group:
if layer.kind == 'pixel':
print(layer.name)
- property blend_mode: BlendMode <#psd_tools.constants.BlendMode>
- Blend mode of this layer. Writable.
- property bottom: int
- Bottom coordinate (computed from children, read-only).
- composite(viewport: tuple[int, int, int, int] | None = None, force: bool = False, color: float | tuple[float, ...] | ndarray = 1.0, alpha: float | ndarray = 0.0, layer_filter: Callable | None = None, apply_icc: bool = True) -> Image | None
- 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().
- Returns
- PIL.Image.Image.
- static extract_bbox(layers: Sequence[Layer <#psd_tools.api.layers.Layer>] | GroupMixin, include_invisible: bool = False) -> tuple[int, int, int, int]
- 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.
- Returns
- tuple of four int
- classmethod group_layers(parent: GroupMixin, layers: Sequence[Layer <#psd_tools.api.layers.Layer>], name: str = 'Group', open_folder: bool = True) -> Self
- 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.
- property left: int
- Left coordinate (computed from children, read-only).
- classmethod new(parent: GroupMixin, name: str = 'Group', open_folder: bool = True) -> Self
- 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.
- property right: int
- Right coordinate (computed from children, read-only).
- property top: int
- Top coordinate (computed from children, read-only).
PixelLayer¶
- class psd_tools.api.layers.PixelLayer(parent: GroupMixin, record: LayerRecord <#psd_tools.psd.layer_and_mask.LayerRecord>, channels: ChannelDataList <#psd_tools.psd.layer_and_mask.ChannelDataList>)
- Layer that has rasterized image in pixels.
Example:
assert layer.kind == 'pixel':
image = layer.composite()
image.save('layer.png')
- classmethod frompil(image: Image, parent: GroupMixin, name: str = 'Layer', top: int = 0, left: int = 0, compression: Compression <#psd_tools.constants.Compression> = Compression.RLE, **kwargs: Any) -> PixelLayer <#psd_tools.api.layers.PixelLayer>
- 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.
ShapeLayer¶
- class psd_tools.api.layers.ShapeLayer(*args: Any)
- Layer that has drawing in vector mask.
- property bbox: tuple[int, int, int, int]
- (left, top, right, bottom) tuple.
SmartObjectLayer¶
- class psd_tools.api.layers.SmartObjectLayer(parent: GroupMixin, record: LayerRecord <#psd_tools.psd.layer_and_mask.LayerRecord>, channels: ChannelDataList <#psd_tools.psd.layer_and_mask.ChannelDataList>)
- 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))
- property smart_object: SmartObject <#psd_tools.api.smart_object.SmartObject>
- Associated smart object.
- Returns
- SmartObject <#psd_tools.api.smart_object.SmartObject>.
TypeLayer¶
- class psd_tools.api.layers.TypeLayer(*args: Any)
- 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
- property document_resources: Dict <#psd_tools.psd.engine_data.Dict>
- Resource set relevant to the document.
- property engine_dict: Dict <#psd_tools.psd.engine_data.Dict>
- Styling information dict.
- property text_type: TextType <#psd_tools.constants.TextType> | None
- Text type. Read-only.
- •
- psd_tools.constants.TextType.POINT <#psd_tools.constants.TextType.POINT> for point type text
- (also known as character type)
- •
- psd_tools.constants.TextType.PARAGRAPH <#psd_tools.constants.TextType.PARAGRAPH> for paragraph type text
- (also known as area type)
- •
- None if text type cannot be determined or information is unavailable
See psd_tools.constants.TextType <#psd_tools.constants.TextType>.
- property transform: tuple[float, float, float, float, float, float]
- Matrix (xx, xy, yx, yy, tx, ty) applies affine transformation.
- property warp: DescriptorBlock | None
- Warp configuration.
psd_tools.api.mask¶
Mask module.
Mask¶
- class psd_tools.api.mask.Mask(layer: LayerProtocol)
- 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.
- property background_color: int
- Background color.
- property bottom: int
- Bottom coordinate.
- property data: MaskData <#psd_tools.psd.layer_and_mask.MaskData>
- Return raw mask data, or None if no data.
- property disabled: bool
- Disabled.
- has_real() -> bool
- Return True if the mask has real flags.
- property height: int
- Height.
- property left: int
- Left coordinate.
- property parameters: Any
- Parameters.
- property right: int
- Right coordinate.
- property size: tuple[int, int]
- (Width, Height) tuple.
- property top: int
- Top coordinate.
- topil(real: bool = True, **kwargs: Any) -> Image | None
- Get PIL Image of the mask.
- Parameters
- real -- When True, returns pixel + vector mask combined.
- Returns
- PIL Image object, or None if the mask is empty.
- property width: int
- Width.
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¶
- class psd_tools.api.shape.VectorMask(data: VectorMaskSetting <#psd_tools.psd.vector.VectorMaskSetting>)
- 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.
- property bbox: tuple[float, float, float, float]
- Bounding box tuple (left, top, right, bottom) in relative coordinates, where top-left corner is (0., 0.) and bottom-right corner is (1., 1.).
- Returns
- tuple
- property clipboard_record: ClipboardRecord <#psd_tools.psd.vector.ClipboardRecord> | None
- Clipboard record containing bounding box information.
Depending on the Photoshop version, this field can be None.
- property disabled: bool
- If the mask is disabled.
- property initial_fill_rule: int
- Initial fill rule.
When 0, fill inside of the path. When 1, fill outside of the shape.
- Returns
- int
- property inverted: bool
- Invert the mask.
- property not_linked: bool
- If the knots are not linked.
- property paths: list[Subpath <#psd_tools.psd.vector.Subpath>]
- 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]
- Returns
- List of Subpath.
Stroke¶
- class psd_tools.api.shape.Stroke(data: VectorStrokeContentSetting <#psd_tools.psd.vector.VectorStrokeContentSetting>)
- 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.
- property blend_mode: Any
- Blend mode.
- property content: Any
- Fill effect.
- property enabled: bool
- If the stroke is enabled.
- property fill_enabled: bool
- If the stroke fill is enabled.
- property line_alignment: str
- Alignment, one of inner, outer, center.
- property line_cap_type: str
- Cap type, one of butt, round, square.
- property line_join_type: str
- Join type, one of miter, round, bevel.
- property line_width: float
- Stroke width in float.
- property miter_limit: Any
- Miter limit in float.
- property opacity: Any
- Opacity value.
- property stroke_adjust: Any
- Stroke adjust
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¶
- class psd_tools.api.shape.Invalidated(data: Descriptor <#psd_tools.psd.descriptor.Descriptor>)
- 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¶
- class psd_tools.api.shape.Line(data: Descriptor <#psd_tools.psd.descriptor.Descriptor>)
- Line live shape.
- property bbox: tuple[float, float, float, float]
- Bounding box of the live shape.
- Returns
- Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Returns
- Descriptor <#psd_tools.psd.descriptor.Descriptor>
- Returns
- Descriptor <#psd_tools.psd.descriptor.Descriptor>
- property origin_type: int
- Type of the vector shape.
- 1: Rectangle
- 2: RoundedRectangle
- 4: Line
- 5: Ellipse
- Returns
- int
Ellipse¶
- class psd_tools.api.shape.Ellipse(data: Descriptor <#psd_tools.psd.descriptor.Descriptor>)
- Ellipse live shape.
- property bbox: tuple[float, float, float, float]
- Bounding box of the live shape.
- Returns
- Descriptor <#psd_tools.psd.descriptor.Descriptor>
- property origin_type: int
- Type of the vector shape.
- 1: Rectangle
- 2: RoundedRectangle
- 4: Line
- 5: Ellipse
- Returns
- int
Rectangle¶
- class psd_tools.api.shape.Rectangle(data: Descriptor <#psd_tools.psd.descriptor.Descriptor>)
- Rectangle live shape.
- property bbox: tuple[float, float, float, float]
- Bounding box of the live shape.
- Returns
- Descriptor <#psd_tools.psd.descriptor.Descriptor>
- property origin_type: int
- Type of the vector shape.
- 1: Rectangle
- 2: RoundedRectangle
- 4: Line
- 5: Ellipse
- Returns
- int
RoundedRectangle¶
- class psd_tools.api.shape.RoundedRectangle(data: Descriptor <#psd_tools.psd.descriptor.Descriptor>)
- Rounded rectangle live shape.
- property bbox: tuple[float, float, float, float]
- Bounding box of the live shape.
- Returns
- Descriptor <#psd_tools.psd.descriptor.Descriptor>
- property origin_type: int
- Type of the vector shape.
- 1: Rectangle
- 2: RoundedRectangle
- 4: Line
- 5: Ellipse
- Returns
- int
- property radii: Any
- Corner radii of rounded rectangles. The order is top-left, top-right, bottom-left, bottom-right.
- Returns
- Descriptor <#psd_tools.psd.descriptor.Descriptor>
psd_tools.api.smart_object¶
Smart object module.
SmartObject¶
- class psd_tools.api.smart_object.SmartObject(layer: LayerProtocol)
- Smart object that represents embedded or external file.
Smart objects are attached to SmartObjectLayer <#psd_tools.api.layers.SmartObjectLayer>.
- property data: bytes
- Embedded file content, or empty if kind is external or alias
- property filename: str
- Original file name of the object.
- property filesize: int
- File size of the object.
- property filetype: str
- Preferred file extension, such as jpg.
- is_psd() -> bool
- Return True if the file is embedded PSD/PSB.
- property kind: str
- Kind of the link, 'data', 'alias', or 'external'.
- open(external_dir: str | None = None) -> Iterator[BinaryIO]
- Open the smart object as binary IO.
- Parameters
- external_dir -- Path to the directory of the external file.
Example:
with layer.smart_object.open() as f:
data = f.read()
- property resolution: float
- Resolution of the object.
- save(filename: str | None = None) -> None
- Save the smart object to a file.
- Parameters
- filename -- File name to export. If None, use the embedded name.
- property transform_box: tuple[float, float, float, float, float, float, float, float] | None
- 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.
- property unique_id: str
- UUID of the object.
- property warp: object | None
- 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¶
- psd_tools.composite.composite(group: Layer <#psd_tools.api.layers.Layer> | PSDImage <#psd_tools.api.psd_image.PSDImage>, color: float | tuple[float, ...] | ndarray = 1.0, alpha: float | ndarray = 0.0, viewport: tuple[int, int, int, int] | None = None, layer_filter: Callable | None = None, force: bool = False, as_layer: bool = False) -> tuple[ndarray, ndarray, ndarray]
- 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.
- Args:
- 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]
- Examples:
-
>>> 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) - Note:
- •
- 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)
- psd_tools.composite.composite_pil(layer: Layer <#psd_tools.api.layers.Layer> | PSDImage <#psd_tools.api.psd_image.PSDImage>, color: float | tuple[float, ...] | ndarray, alpha: float | ndarray, viewport: tuple[int, int, int, int] | None, layer_filter: Callable | None, force: bool, as_layer: bool = False, apply_icc: bool = True) -> Image | None
- 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.
- Args:
- 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)
- Returns:
- PIL Image with composited result, or None if viewport is empty
- Note:
- 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.
- psd_tools.composite.blend.divide(Cb: ndarray, Cs: ndarray) -> ndarray
- Looks at the color information in each channel and divides the blend color from the base color.
- psd_tools.composite.blend.hard_mix(Cb: ndarray, Cs: ndarray) -> ndarray
- 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.
- psd_tools.composite.blend.linear_light(Cb: ndarray, Cs: ndarray) -> ndarray
- 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.
- psd_tools.composite.blend.non_separable(k: str = 's')
- Wrap non-separable blending function for CMYK handling.
- psd_tools.composite.blend.pin_light(Cb: ndarray, Cs: ndarray) -> ndarray
- 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.
- psd_tools.composite.blend.vivid_light(Cb: ndarray, Cs: ndarray) -> ndarray
- 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.
- psd_tools.composite.vector.draw_stroke(layer)
- Draw a stroke.
Requires aggdraw for bezier curve rasterization.
- psd_tools.composite.vector.draw_vector_mask(layer)
- 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¶
- psd_tools.compression.compress(data: bytes, compression: Compression <#psd_tools.constants.Compression>, width: int, height: int, depth: int, version: int = 1) -> bytes
- 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.
- Returns
- compressed data bytes.
- psd_tools.compression.decompress(data: bytes, compression: Compression <#psd_tools.constants.Compression>, width: int, height: int, depth: int, version: int = 1) -> 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.
- Returns
- 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¶
- class psd_tools.constants.CompatibilityMode(*values)
- Compatibility modes that describe how compositing and layer control should attempt to behave.
Compression¶
- class psd_tools.constants.Compression(*values)
- Compression modes.
Compression. 0 = Raw Data, 1 = RLE compressed, 2 = ZIP without prediction, 3 = ZIP with prediction.
EffectOSType¶
GlobalLayerMaskKind¶
LinkedLayerType¶
PathResourceID¶
PlacedLayerType¶
PrintScaleStyle¶
Resource¶
- class psd_tools.constants.Resource(*values)
- 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¶
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¶
- class psd_tools.psd.PSD(header: FileHeader <#psd_tools.psd.header.FileHeader> = NOTHING, color_mode_data: ColorModeData <#psd_tools.psd.color_mode_data.ColorModeData> = NOTHING, image_resources: ImageResources <#psd_tools.psd.image_resources.ImageResources> = NOTHING, layer_and_mask_information: LayerAndMaskInformation <#psd_tools.psd.layer_and_mask.LayerAndMaskInformation> = NOTHING, image_data: ImageData <#psd_tools.psd.image_data.ImageData> = NOTHING)
- 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)
- header
- See FileHeader <#psd_tools.psd.header.FileHeader>.
- color_mode_data
- See ColorModeData <#psd_tools.psd.color_mode_data.ColorModeData>.
- image_resources
- See ImageResources <#psd_tools.psd.image_resources.ImageResources>.
- layer_and_mask_information
- See LayerAndMaskInformation <#psd_tools.psd.layer_and_mask.LayerAndMaskInformation>.
- image_data
- 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¶
- class psd_tools.psd.base.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.
- classmethod read(cls, fp)
- Read the element from a file-like object.
- write(self, fp)
- Write the element to a file-like object.
- classmethod frombytes(self, data, *args, **kwargs)
- Read the element from bytes.
- tobytes(self, *args, **kwargs)
- Write the element to bytes.
- validate(self)
- Validate the attribute.
EmptyElement¶
- class psd_tools.psd.base.EmptyElement
- Empty element that does not have a value.
ValueElement¶
- class psd_tools.psd.base.ValueElement(value: object = None)
- 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.
- value
- Internal value.
NumericElement¶
- class psd_tools.psd.base.NumericElement(value=0.0)
- Single value element that has a numeric value attribute.
IntegerElement¶
- class psd_tools.psd.base.IntegerElement(value=0)
- Single integer value element that has a value attribute.
Use with @define(repr=False) decorator.
ShortIntegerElement¶
- class psd_tools.psd.base.ShortIntegerElement(value=0)
- Single short integer element that has a value attribute.
Use with @define(repr=False) decorator.
ByteElement¶
- class psd_tools.psd.base.ByteElement(value=0)
- Single 1-byte integer element that has a value attribute.
Use with @define(repr=False) decorator.
BooleanElement¶
- class psd_tools.psd.base.BooleanElement(value=False)
- Single bool value element that has a value attribute.
Use with @define(repr=False) decorator.
StringElement¶
ListElement¶
- class psd_tools.psd.base.ListElement(items=NOTHING)
- List-like element that has items list.
DictElement¶
- class psd_tools.psd.base.DictElement(items=NOTHING)
- Dict-like element that has items OrderedDict.
psd_tools.psd.color_mode_data¶
Color mode data structure.
ColorModeData¶
- class psd_tools.psd.color_mode_data.ColorModeData(value: bytes = b'')
- 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.
- interleave() -> bytes
- 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¶
- class psd_tools.psd.descriptor.Alias(value: bytes = b'\x00\x00\x00\x00')
- Alias structure equivalent to RawData.
Bool¶
Class¶
- class psd_tools.psd.descriptor.Class(name: str = '', classID: bytes = b'\x00\x00\x00\x00')
- Class structure.
- name
- str value
- classID
- bytes in Klass <#psd_tools.terminology.Klass>
Class1¶
- class psd_tools.psd.descriptor.Class1(name: str = '', classID: bytes = b'\x00\x00\x00\x00')
- Class structure equivalent to Class.
Class2¶
- class psd_tools.psd.descriptor.Class2(name: str = '', classID: bytes = b'\x00\x00\x00\x00')
- Class structure equivalent to Class.
Class3¶
- class psd_tools.psd.descriptor.Class3(name: str = '', classID: bytes = b'\x00\x00\x00\x00')
- Class structure equivalent to Class.
Descriptor¶
- class psd_tools.psd.descriptor.Descriptor(items=NOTHING, name: str = '', classID: bytes = b'null')
- 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])
- name
- str
- classID
- bytes in Klass <#psd_tools.terminology.Klass>
Double¶
Enumerated¶
- class psd_tools.psd.descriptor.Enumerated(typeID: bytes = b'\x00\x00\x00\x00', enum: bytes = b'\x00\x00\x00\x00')
- Enum structure.
- typeID
- bytes in Type <#psd_tools.terminology.Type>
- enum
- bytes in Enum <#psd_tools.terminology.Enum>
- get_name() -> str
- Get enum name.
EnumeratedReference¶
- class psd_tools.psd.descriptor.EnumeratedReference(name: str = '', classID: bytes = b'\x00\x00\x00\x00', typeID: bytes = b'\x00\x00\x00\x00', enum: bytes = b'\x00\x00\x00\x00')
- Enumerated reference structure.
- name
- str value
- classID
- bytes in Klass <#psd_tools.terminology.Klass>
- typeID
- bytes in Type <#psd_tools.terminology.Type>
- enum
- bytes in Enum <#psd_tools.terminology.Enum>
GlobalObject¶
- class psd_tools.psd.descriptor.GlobalObject(items=NOTHING, name: str = '', classID: bytes = b'null')
- Global object structure equivalent to Descriptor.
Identifier¶
- class psd_tools.psd.descriptor.Identifier(value=0)
- Identifier equivalent to Integer.
Index¶
- class psd_tools.psd.descriptor.Index(value=0)
- Index equivalent to Integer.
Integer¶
LargeInteger¶
List¶
- class psd_tools.psd.descriptor.List(items=NOTHING)
- List structure.
Example:
for item in list_value:
print(item)
Name¶
- class psd_tools.psd.descriptor.Name(name: str = '', classID: bytes = b'\x00\x00\x00\x00', value: str = '')
- Name structure (Undocumented).
- name
- str
- classID
- bytes in Klass <#psd_tools.terminology.Klass>
- value
- str
ObjectArray¶
- class psd_tools.psd.descriptor.ObjectArray(items=NOTHING, items_count: int = 0, name: str = '', classID: bytes = b'null')
- Object array structure almost equivalent to Descriptor.
- items_count
- int value
- name
- str value
- classID
- bytes in Klass <#psd_tools.terminology.Klass>
Property¶
- class psd_tools.psd.descriptor.Property(name: str = '', classID: bytes = b'\x00\x00\x00\x00', keyID: bytes = b'\x00\x00\x00\x00')
- Property structure.
- name
- str value
- classID
- bytes in Klass <#psd_tools.terminology.Klass>
- keyID
- bytes in Key <#psd_tools.terminology.Key>
Offset¶
- class psd_tools.psd.descriptor.Offset(name: str = '', classID: bytes = b'\x00\x00\x00\x00', value: int = 0)
- Offset structure.
- name
- str value
- classID
- bytes in Klass <#psd_tools.terminology.Klass>
- value
- int value
Path¶
- class psd_tools.psd.descriptor.Path(value: bytes = b'\x00\x00\x00\x00')
- Undocumented path structure equivalent to RawData.
RawData¶
- class psd_tools.psd.descriptor.RawData(value: bytes = b'\x00\x00\x00\x00')
- RawData structure.
- value
- bytes value
Reference¶
- class psd_tools.psd.descriptor.Reference(items=NOTHING)
- Reference structure equivalent to List.
String¶
UnitFloat¶
- class psd_tools.psd.descriptor.UnitFloat(value: float = 0.0, unit: Unit <#psd_tools.terminology.Unit> = Unit._None)
- Unit float structure.
- unit
- unit of the value in Unit or Enum
- value
- float value
UnitFloats¶
- class psd_tools.psd.descriptor.UnitFloats(unit: Unit <#psd_tools.terminology.Unit> = Unit._None, values: list = NOTHING)
- Unit floats structure.
- unit
- unit of the value in Unit or Enum
- values
- List of float values
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¶
- class psd_tools.psd.engine_data.EngineData(items=NOTHING)
- Dict-like element.
TYPE_TOOL_OBJECT_SETTING tagged block contains this object in its descriptor.
EngineData2¶
- class psd_tools.psd.engine_data.EngineData2(items=NOTHING)
- Dict-like element.
TEXT_ENGINE_DATA tagged block has this object.
Bool¶
- class psd_tools.psd.engine_data.Bool(value=False)
- Bool element.
Dict¶
- class psd_tools.psd.engine_data.Dict(items=NOTHING)
- Dict-like element.
Float¶
- class psd_tools.psd.engine_data.Float(value=0.0)
- Float element.
Integer¶
- class psd_tools.psd.engine_data.Integer(value=0)
- Integer element.
List¶
- class psd_tools.psd.engine_data.List(items=NOTHING)
- List-like element.
Property¶
- class psd_tools.psd.engine_data.Property(value: object = None)
- Property element.
String¶
- class psd_tools.psd.engine_data.String(value: object = None)
- String element.
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¶
- class psd_tools.psd.effects_layer.EffectsLayer(items=NOTHING, version: int = 0)
- Dict-like EffectsLayer structure. See psd_tools.constants.EffectOSType <#psd_tools.constants.EffectOSType> for available keys.
CommonStateInfo¶
- class psd_tools.psd.effects_layer.CommonStateInfo(version: int = 0, visible: int = 1)
- Effects layer common state info.
ShadowInfo¶
OuterGlowInfo¶
- class psd_tools.psd.effects_layer.OuterGlowInfo(version: int = 0, blur: int = 0, intensity: int = 0, color: Color = NOTHING, blend_mode=BlendMode.NORMAL, enabled: int = 0, opacity: int = 0, native_color: object = None)
- Effects layer outer glow info.
InnerGlowInfo¶
- class psd_tools.psd.effects_layer.InnerGlowInfo(version: int = 0, blur: int = 0, intensity: int = 0, color: Color = NOTHING, blend_mode=BlendMode.NORMAL, enabled: int = 0, opacity: int = 0, invert: int | None = None, native_color: object | None = None)
- Effects layer inner glow info.
BevelInfo¶
SolidFillInfo¶
- class psd_tools.psd.effects_layer.SolidFillInfo(version: int = 2, blend_mode=BlendMode.NORMAL, color: Color = NOTHING, opacity: int = 0, enabled: int = 0, native_color: Color = NOTHING)
- Effects layer inner glow info.
psd_tools.psd.filter_effects¶
Filter effects structure.
FilterEffects¶
- class psd_tools.psd.filter_effects.FilterEffects(items=NOTHING, version: int = 1)
- List-like FilterEffects structure. See FilterEffect.
FilterEffect¶
FilterEffectChannel¶
- class psd_tools.psd.filter_effects.FilterEffectChannel(is_written: int = 0, compression: int | None = None, data: bytes = b'')
- FilterEffectChannel structure.
FilterEffectExtra¶
- class psd_tools.psd.filter_effects.FilterEffectExtra(is_written: int = 0, rectangle=NOTHING, compression: int = 0, data: bytes = b'')
- FilterEffectExtra structure.
psd_tools.psd.header¶
File header structure.
FileHeader¶
- class psd_tools.psd.header.FileHeader(signature: bytes = b'8BPS', version: int = 1, channels: int = 4, height: int = 64, width: int = 64, depth: int = 8, color_mode=ColorMode.RGB)
- 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
- Signature: always equal to b'8BPS'.
- version
- Version number. PSD is 1, and PSB is 2.
- channels
- The number of channels in the image, including any user-defined alpha channel.
- height
- The height of the image in pixels.
- width
- The width of the image in pixels.
- depth
- The number of bits per channel.
- color_mode
- 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¶
- class psd_tools.psd.image_data.ImageData(compression=Compression.RAW, data: bytes = b'')
- Merged channel image data.
- compression
- See Compression <#psd_tools.constants.Compression>.
- data
- bytes as compressed in the compression flag.
- get_data(header: FileHeader <#psd_tools.psd.header.FileHeader>, split: bool = True) -> list[bytes] | bytes
- Get decompressed data.
- Parameters
- header -- See FileHeader <#psd_tools.psd.header.FileHeader>.
- Returns
- list of bytes corresponding each channel.
- classmethod new(header: FileHeader <#psd_tools.psd.header.FileHeader>, color: int | Sequence[int] = 0, compression: Compression <#psd_tools.constants.Compression> = Compression.RAW) -> T
- Create a new image data object.
- header -- FileHeader.
- compression -- compression type.
- color -- default color. int or iterable for channel length.
- set_data(data: Sequence[bytes], header: FileHeader <#psd_tools.psd.header.FileHeader>) -> int
- 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>.
- Returns
- 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¶
- class psd_tools.psd.image_resources.ImageResources(items=NOTHING)
- Image resources section of the PSD file. Dict of ImageResource.
- get_data(key: Any, default: Any = None) -> Any
- Get data from the image resources.
Shortcut for the following:
if key in image_resources:
value = tagged_blocks[key].data
- classmethod new(**kwargs: Any) -> T_ImageResources
- Create a new default image resouces.
- Returns
- ImageResources
ImageResource¶
- class psd_tools.psd.image_resources.ImageResource(signature: bytes = b'8BIM', key: int = 1000, name: str = '', data: bytes = b'')
- Image resource block.
- signature
- Binary signature, always b'8BIM'.
- key
- Unique identifier for the resource. See Resource <#psd_tools.constants.Resource>.
- data
- The resource data.
AlphaIdentifiers¶
- class psd_tools.psd.image_resources.AlphaIdentifiers(items=NOTHING)
- List of alpha identifiers.
AlphaNamesPascal¶
- class psd_tools.psd.image_resources.AlphaNamesPascal(items=NOTHING)
- List of alpha names.
AlphaNamesUnicode¶
- class psd_tools.psd.image_resources.AlphaNamesUnicode(items=NOTHING)
- List of alpha names.
Byte¶
- class psd_tools.psd.image_resources.Byte(value=0)
- Byte element.
GridGuidesInfo¶
- class psd_tools.psd.image_resources.GridGuidesInfo(version: int = 1, horizontal: int = 0, vertical: int = 0, data=NOTHING)
- Grid and guides info structure.
HalftoneScreens¶
- class psd_tools.psd.image_resources.HalftoneScreens(items=NOTHING)
- Halftone screens.
HalftoneScreen¶
Integer¶
- class psd_tools.psd.image_resources.Integer(value=0)
- Integer element.
LayerGroupEnabledIDs¶
- class psd_tools.psd.image_resources.LayerGroupEnabledIDs(items=NOTHING)
- Layer group enabled ids.
LayerGroupInfo¶
- class psd_tools.psd.image_resources.LayerGroupInfo(items=NOTHING)
- Layer group info list.
LayerSelectionIDs¶
- class psd_tools.psd.image_resources.LayerSelectionIDs(items=NOTHING)
- Layer selection ids.
ShortInteger¶
- class psd_tools.psd.image_resources.ShortInteger(value=0)
- Short integer element.
PascalString¶
- class psd_tools.psd.image_resources.PascalString(value: object = None)
- Pascal string element.
PixelAspectRatio¶
PrintFlags¶
PrintFlagsInfo¶
- class psd_tools.psd.image_resources.PrintFlagsInfo(version: int = 0, center_crop: int = 0, bleed_width_value: int = 0, bleed_width_scale: int = 0)
- Print flags info structure.
PrintScale¶
- class psd_tools.psd.image_resources.PrintScale(style=PrintScaleStyle.CENTERED, x: float = 0.0, y: float = 0.0, scale: float = 0.0)
- Print scale structure.
ResoulutionInfo¶
- class psd_tools.psd.image_resources.ResoulutionInfo(horizontal: int = 0, horizontal_unit: int = 0, width_unit: int = 0, vertical: int = 0, vertical_unit: int = 0, height_unit: int = 0)
- Resoulution info structure.
Slices¶
SlicesV6¶
- class psd_tools.psd.image_resources.SlicesV6(bbox=NOTHING, name: str = '', items=NOTHING)
- Slices resource version 6.
SliceV6¶
ThumbnailResource¶
- class psd_tools.psd.image_resources.ThumbnailResource(fmt: int = 0, width: int = 0, height: int = 0, row: int = 0, total_size: int = 0, bits: int = 0, planes: int = 0, data: bytes = b'')
- Thumbnail resource structure.
ThumbnailResourceV4¶
TransferFunctions¶
- class psd_tools.psd.image_resources.TransferFunctions(items=NOTHING)
- Transfer functions.
TransferFunction¶
URLList¶
- class psd_tools.psd.image_resources.URLList(items=NOTHING)
- URL list structure.
URLItem¶
VersionInfo¶
- class psd_tools.psd.image_resources.VersionInfo(version: int = 1, has_composite: bool = False, writer: str = '', reader: str = '', file_version: int = 1)
- Version info structure.
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¶
- layer_info
- See LayerInfo.
- global_layer_mask_info
- See GlobalLayerMaskInfo.
- tagged_blocks
- See TaggedBlocks <#psd_tools.psd.tagged_blocks.TaggedBlocks>.
LayerInfo¶
- class psd_tools.psd.layer_and_mask.LayerInfo(layer_count: int = 0, layer_records: LayerRecords <#psd_tools.psd.layer_and_mask.LayerRecords> = NOTHING, channel_image_data: ChannelImageData <#psd_tools.psd.layer_and_mask.ChannelImageData> = NOTHING)
- High-level organization of the layer information.
- layer_count
- 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.
- layer_records
- Information about each layer. See LayerRecords.
- channel_image_data
- Channel image data. See ChannelImageData.
GlobalLayerMaskInfo¶
- class psd_tools.psd.layer_and_mask.GlobalLayerMaskInfo(overlay_color: list[int] | None = None, opacity: int = 0, kind=GlobalLayerMaskKind.PER_LAYER)
- Global mask information.
- overlay_color
- Overlay color space (undocumented) and color components.
- opacity
- Opacity. 0 = transparent, 100 = opaque.
- kind
- 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¶
- class psd_tools.psd.layer_and_mask.LayerRecords(items=NOTHING)
- List of layer records. See LayerRecord.
LayerRecord¶
- top
- Top position.
- left
- Left position.
- bottom
- Bottom position.
- right
- Right position.
- channel_info
- List of ChannelInfo.
- signature
- Blend mode signature b'8BIM'.
- blend_mode
- Blend mode key. See BlendMode <#psd_tools.constants.BlendMode>.
- opacity
- Opacity, 0 = transparent, 255 = opaque.
- clipping
- Clipping, 0 = base, 1 = non-base. See Clipping <#psd_tools.constants.Clipping>.
- flags
- See LayerFlags.
- mask_data
- MaskData or None.
- blending_ranges
- See LayerBlendingRanges.
- name
- Layer name.
- tagged_blocks
- See TaggedBlocks <#psd_tools.psd.tagged_blocks.TaggedBlocks>.
- property channel_sizes: list[tuple[int, int]]
- List of channel sizes: [(width, height)].
- property height: int
- Height of the layer.
- property width: int
- Width of the layer.
LayerFlags¶
- class psd_tools.psd.layer_and_mask.LayerFlags(transparency_protected: bool = False, visible: bool = True, obsolete: bool = False, photoshop_v5_later: bool = True, pixel_data_irrelevant: bool = False, undocumented_1: bool = False, undocumented_2: bool = False, undocumented_3: bool = False)
- Layer flags.
Note there are undocumented flags. Maybe photoshop version.
LayerBlendingRanges¶
- class psd_tools.psd.layer_and_mask.LayerBlendingRanges(composite_ranges: list[tuple[int, int]] = NOTHING, channel_ranges: list[list[tuple[int, int]]] = NOTHING)
- Layer blending ranges.
All ranges contain 2 black values followed by 2 white values.
- composite_ranges
- List of composite gray blend source and destination ranges.
- channel_ranges
- List of channel source and destination ranges.
MaskData¶
- class psd_tools.psd.layer_and_mask.MaskData(top: int = 0, left: int = 0, bottom: int = 0, right: int = 0, background_color: int = 0, flags: MaskFlags <#psd_tools.psd.layer_and_mask.MaskFlags> = NOTHING, parameters: object = None, real_flags: object = None, real_background_color: int | None = None, real_top: int | None = None, real_left: int | None = None, real_bottom: int | None = None, real_right: int | None = None)
- Mask data.
Real user mask is a final composite mask of vector and pixel masks.
- top
- Top position.
- left
- Left position.
- bottom
- Bottom position.
- right
- Right position.
- background_color
- Default color. 0 or 255.
- flags
- See MaskFlags.
- parameters
- MaskParameters or None.
- real_flags
- Real user mask flags. See MaskFlags.
- real_background_color
- Real user mask background. 0 or 255.
- real_top
- Top position of real user mask.
- real_left
- Left position of real user mask.
- real_bottom
- Bottom position of real user mask.
- real_right
- Right position of real user mask.
- property height: int
- Height of the mask.
- property real_height: int
- Height of real user mask.
- property real_width: int
- Width of real user mask.
- property width: int
- Width of the mask.
MaskFlags¶
- pos_relative_to_layer
- Position relative to layer.
- mask_disabled
- Layer mask disabled.
- invert_mask
- Invert layer mask when blending (Obsolete).
- user_mask_from_render
- The user mask actually came from rendering other data.
- parameters_applied
- The user and/or vector masks have parameters applied to them.
MaskParameters¶
ChannelInfo¶
- class psd_tools.psd.layer_and_mask.ChannelInfo(id=ChannelID.CHANNEL_0, length: int = 0)
- Channel information.
- id
- 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
- Length of the corresponding channel data.
ChannelImageData¶
- class psd_tools.psd.layer_and_mask.ChannelImageData(items=NOTHING)
- 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¶
- class psd_tools.psd.layer_and_mask.ChannelDataList(items=NOTHING)
- List of channel image data, corresponding to each color or alpha.
See ChannelData.
ChannelData¶
- class psd_tools.psd.layer_and_mask.ChannelData(compression=Compression.RAW, data: bytes = b'')
- Channel data.
- compression
- Compression type. See Compression <#psd_tools.constants.Compression>.
- data
- Data.
- get_data(width: int, height: int, depth: int, version: int = 1) -> bytes
- Get decompressed channel data.
- width -- width.
- height -- height.
- depth -- bit depth of the pixel.
- version -- psd file version.
- Return type
- bytes
- set_data(data: bytes, width: int, height: int, depth: int, version: int = 1) -> int
- 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¶
- class psd_tools.psd.linked_layer.LinkedLayers(items=NOTHING)
- List of LinkedLayer structure. See LinkedLayer.
LinkedLayer¶
psd_tools.psd.patterns¶
Patterns structure.
Patterns¶
- class psd_tools.psd.patterns.Patterns(items=NOTHING)
- List of Pattern structure. See Pattern.
Pattern¶
- image_mode
- See ColorMode
- point
- Size in tuple.
- name
- str name of the pattern.
- pattern_id
- ID of this pattern.
- color_table
- Color table if the mode is INDEXED.
- data
- See VirtualMemoryArrayList
VirtualMemoryArrayList¶
- class psd_tools.psd.patterns.VirtualMemoryArrayList(version: int = 3, rectangle: tuple[int, int, int, int] = (0, 0, 0, 0), channels: list[VirtualMemoryArray <#psd_tools.psd.patterns.VirtualMemoryArray>] = NOTHING)
- VirtualMemoryArrayList structure. Container of channels.
- rectangle
- Tuple of int
- channels
- List of VirtualMemoryArray
VirtualMemoryArray¶
- class psd_tools.psd.patterns.VirtualMemoryArray(is_written: int = 0, depth: int | None = None, rectangle: tuple[int, int, int, int] | None = None, pixel_depth: int | None = None, compression=Compression.RAW, data: bytes = b'')
- VirtualMemoryArrayList structure, corresponding to each channel.
- get_data() -> bytes | None
- Get decompressed bytes.
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¶
- class psd_tools.psd.tagged_blocks.TaggedBlocks(items=NOTHING)
- 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¶
- class psd_tools.psd.tagged_blocks.TaggedBlock(signature: bytes = b'8BIM', key: bytes = b'', data: bytes = b'')
- Layer tagged block with extra info.
- key
- 4-character code. See Tag <#psd_tools.constants.Tag>
- data
- Data.
Annotations¶
- class psd_tools.psd.tagged_blocks.Annotations(items=NOTHING, major_version: int = 2, minor_version: int = 1)
- List of Annotation, see :py:class: .Annotation.
Annotation¶
Bytes¶
ChannelBlendingRestrictionsSetting¶
- class psd_tools.psd.tagged_blocks.ChannelBlendingRestrictionsSetting(items=NOTHING)
- ChannelBlendingRestrictionsSetting structure.
List of restricted channel numbers (int).
FilterMask¶
- class psd_tools.psd.tagged_blocks.FilterMask(color: Color = NOTHING, opacity: int = 0)
- FilterMask structure.
MetadataSettings¶
- class psd_tools.psd.tagged_blocks.MetadataSettings(items=NOTHING)
- MetadataSettings structure.
MetadataSetting¶
PixelSourceData2¶
- class psd_tools.psd.tagged_blocks.PixelSourceData2(items=NOTHING)
- PixelSourceData2 structure.
PlacedLayerData¶
ProtectedSetting¶
- class psd_tools.psd.tagged_blocks.ProtectedSetting(value=0)
- ProtectedSetting structure.
ReferencePoint¶
- class psd_tools.psd.tagged_blocks.ReferencePoint(items=NOTHING)
- ReferencePoint structure.
SectionDividerSetting¶
- class psd_tools.psd.tagged_blocks.SectionDividerSetting(kind=SectionDivider.OTHER, signature: bytes | None = None, blend_mode: BlendMode <#psd_tools.constants.BlendMode> | None = None, sub_type: int | None = None)
- SectionDividerSetting structure.
SheetColorSetting¶
- class psd_tools.psd.tagged_blocks.SheetColorSetting(value=SheetColorType.NO_COLOR)
- SheetColorSetting value.
This setting represents color label in the layers panel in Photoshop UI.
SmartObjectLayerData¶
- class psd_tools.psd.tagged_blocks.SmartObjectLayerData(kind: bytes = b'soLD', version: int = 5, data: DescriptorBlock = NOTHING)
- VersionedDescriptorBlock structure.
TypeToolObjectSetting¶
UserMask¶
- class psd_tools.psd.tagged_blocks.UserMask(color: Color = NOTHING, opacity: int = 0, flag: int = 128)
- UserMask structure.
psd_tools.psd.vector¶
Vector mask, path, and stroke structure.
Path¶
- class psd_tools.psd.vector.Path(items=NOTHING)
- List-like Path structure. Elements are either PathFillRule, InitialFillRule, ClipboardRecord, ClosedPath, or OpenPath.
Subpath¶
- class psd_tools.psd.vector.Subpath(items=NOTHING, operation: int = 1, unknown1: int = 1, unknown2: int = 0, index: int = 0, unknown3: bytes = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
- Subpath element. This is a list of Knot objects.
Note:
- operation
- 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.
- index
- int index that specifies corresponding origination object.
Knot¶
- class psd_tools.psd.vector.Knot(preceding: tuple = (0.0,), anchor: tuple = (0.0,), leaving: tuple = (0.0,))
- Knot element consisting of 3 control points for Bezier curves.
- preceding
- (y, x) tuple of preceding control point in relative coordinates.
- anchor
- (y, x) tuple of anchor point in relative coordinates.
- leaving
- (y, x) tuple of leaving control point in relative coordinates.
ClipboardRecord¶
- class psd_tools.psd.vector.ClipboardRecord(top: int = 0, left: int = 0, bottom: int = 0, right: int = 0, resolution: int = 0)
- Clipboard record.
- top
- Top position in int
- left
- Left position in int
- bottom
- Bottom position in int
- right
- Right position in int
- resolution
- Resolution in int
PathFillRule¶
- class psd_tools.psd.vector.PathFillRule
- Path fill rule record, empty.
InitialFillRule¶
- class psd_tools.psd.vector.InitialFillRule(value=0)
- Initial fill rule record.
- rule
- A value of 1 means that the fill starts with all pixels. The value will be either 0 or 1.
VectorMaskSetting¶
- class psd_tools.psd.vector.VectorMaskSetting(version: int = 3, flags: int = 0, path: Path <#psd_tools.psd.vector.Path> | None = None)
- VectorMaskSetting structure.
- path
- List of Subpath objects.
- property disable: bool
- Flag to indicate that the vector mask is disabled.
- property invert: bool
- Flag to indicate that the vector mask is inverted.
- property not_link: bool
- Flag to indicate that the vector mask is not linked.
VectorStrokeContentSetting¶
- class psd_tools.psd.vector.VectorStrokeContentSetting(items=NOTHING, name: str = '', classID: bytes = b'null', key: bytes = b'\x00\x00\x00\x00', version: int = 1)
- Dict-like Descriptor-based structure. See Descriptor <#psd_tools.psd.descriptor.Descriptor>.
psd_tools.terminology¶
Constants for descriptor.
This file is automaticaly generated by tools/extract_terminology.py
Klass¶
- class psd_tools.terminology.Klass(*values)
- Klass definitions extracted from PITerminology.h.
- 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¶
- class psd_tools.terminology.Enum(*values)
- Enum definitions extracted from PITerminology.h.
- 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¶
- class psd_tools.terminology.Event(*values)
- Event definitions extracted from PITerminology.h.
- 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¶
- class psd_tools.terminology.Form(*values)
- Form definitions extracted from PITerminology.h.
- Class = b'Clss'
- Enumerated = b'Enmr'
- Identifier = b'Idnt'
- Index = b'indx'
- Offset = b'rele'
- Property = b'prop'
Key¶
- class psd_tools.terminology.Key(*values)
- Key definitions extracted from PITerminology.h.
- 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¶
- class psd_tools.terminology.Type(*values)
- Type definitions extracted from PITerminology.h.
- BlendMode = b'BlnM'
- GlobalObject = b'GlbO'
- RawData = b'tdta'
- UnitFloat = b'UntF'
Unit¶
- class psd_tools.terminology.Unit(*values)
- Unit definitions extracted from PITerminology.h.
- _None = b'#Nne'
INDICES AND TABLES¶
- Index <>
- Module Index <>
- Search Page <>
Author¶
Kota Yamaguchi
Copyright¶
2019, Kota Yamaguchi
| November 30, 2025 | 1.12.0 |