Contributing

Development happens at github: bug tracker. Feel free to submit bug reports 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: subpackage that reads/writes low-level binary

    structure of the PSD/PSB file. The core data structures are built around attrs classes that all implement read and write methods. Each data object tries to resemble the structure described in the specification. Although documented, the specification 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.

  1. psd_tools.api: User-facing API that implements various

    easy-to-use methods that manipulate low-level psd_tools.psd data structures. This is the primary interface for most users.

  2. 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.

  3. 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 on top of the existing psd-tools API.

Testing

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

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

Then install psd-tools with development dependencies:

uv sync --group dev --extra composite

Finally, run tests:

uv run pytest

Documentation

Install documentation dependencies:

uv sync --group docs

Once installed, use Makefile:

make docs

Release Process

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

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

    git checkout main
    git pull origin main
    
  2. Create and push a version tag:

    git tag v1.x.x
    git push origin v1.x.x
    
  3. Automated workflow:

    Once the tag is pushed, the release workflow automatically:

    • Builds wheels for all supported platforms (Linux, Windows, macOS including ARM)

    • Generates release notes from git commits since the previous tag

    • Creates a GitHub release with the auto-generated changelog

    • Publishes the package to PyPI

  4. Verify the release:

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

Acknowledgments

Great thanks to all the contributors.