# 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` 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`.

Key modules:

- `psd_tools.api.psd_image`: Main PSDImage class for document operations

- `psd_tools.api.layers`: Layer type hierarchy (Layer, GroupMixin, etc.)

- `psd_tools.api.adjustments`: Adjustment layer types

- `psd_tools.api.mask`: Layer mask operations

- `psd_tools.api.shape`: Vector shape and stroke operations

- `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` structures with convenient Pythonic interfaces.

## PSDImage

class psd_tools.api.psd_image.PSDImage(data: 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) → 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 background_color: float | tuple[float, ...] | None

    Background color for the merged composite image. Writable.

    When set, `save()` composites layers against an opaque backdrop of this color instead of a transparent one. This is useful for creating RGB-mode PSD files where transparent areas should appear as a specific color (e.g., white) in the merged composite.

    Values are in [0.0, 1.0] range, matching the `composite()` `color` parameter:

    - RGB / Grayscale: `1.0` = white, `0.0` = black

    - CMYK: `(0.0, 0.0, 0.0, 0.0)` = white (no ink)

    Use a scalar for uniform color or a tuple for per-channel values. Set to `None` for transparent backdrop (legacy behavior).

    Documents created via `new()` have this set automatically from the `color` parameter.

    Returns:

      float, tuple[float, …], or None

    Example:

        psd = PSDImage.new('RGB', (640, 480), color=1.0)
        psd.save('output.psd')  # White background, 3 channels (no alpha)

  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.

  property bottom: int

    Bottom coordinate.

    Returns:

      int

  property channels: int

    Number of color channels.

    Returns:

      int

  clear() → None

    Clears the group.

    This operation rewrites the internal references of the layers.

    Returns:

      None

  property color_mode: ColorMode

    Document color mode, such as ‘RGB’ or ‘GRAYSCALE’. See `ColorMode`.

    Returns:

      `ColorMode`

  property compatibility_mode: 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`

  composite(viewport: tuple[int, int, int, int] | None = None, force: bool = False, color: float | tuple[float, ...] | ndarray | None = 1.0, alpha: float | ndarray = 0.0, layer_filter: Callable | None = None, ignore_preview: bool = False, apply_icc: bool = True) → Image

    Composite the PSD image.

    Parameters:

      - 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) → int

    Counts the number of occurrences of a layer in the group.

    Parameters:

      layer – The layer to count.

  create_group(layer_list: Iterable[Layer] | None = None, name: str = 'Group', opacity: int = 255, blend_mode: BlendMode = BlendMode.PASS_THROUGH, open_folder: bool = True) → 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'))

    Parameters:

      - 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` object.

  create_pixel_layer(image: Image, name: str = 'Layer', top: int = 0, left: int = 0, compression: Compression = Compression.RLE, opacity: int = 255, blend_mode: BlendMode = BlendMode.NORMAL) → 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')

    Parameters:

      - 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` object.

  property depth: int

    Pixel depth bits.

    Returns:

      int

  descendants(include_clip: bool = True) → Iterator[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]) → 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 | None

    Returns the first layer found for the given layer name

    Parameters:

      name

  findall(name: str) → Iterator[Layer]

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

    Parameters:

      name

  classmethod frompil(image: Image, compression: Compression = Compression.RLE, color: int | float | Sequence[int | float] | None = None) → Self

    Create a new layer-less PSD document from PIL Image.

    Parameters:

      - image – PIL Image object.

      - compression – ImageData compression option. See `Compression`.

      - color – Background color for the compositing backdrop when saving. Accepts the same types as `new()` `color`. When set, `save()` will composite layers against an opaque backdrop of this color.

    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 height: int

    Document height.

    Returns:

      int

  property image_resources: ImageResources

    Document image resources. `ImageResources` is a dict-like structure that keeps various document settings.

    See `psd_tools.constants.Resource` for available keys.

    Returns:

      `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) → int

    Returns the index of the specified layer in the group.

    Parameters:

      layer – The layer to find.

  insert(index: int, layer: Layer) → None

    Insert the given layer at the specified index.

    This operation rewrites the internal references of the layer.

    Parameters:

      - index – The index to insert the layer at.

      - layer – The layer to insert.

    Raises:

      - 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_updated() → bool

    Returns whether the layer tree has been updated.

    Returns:

      bool

  is_visible() → bool

    Returns visibility of the element.

  property kind: str

    Kind.

    Returns:

      ‘psdimage’

  property left: int

    Left coordinate.

    Returns:

      0

  property name: str

    Element name.

    Returns:

      ‘Root’

  classmethod new(mode: str, size: tuple[int, int], color: int | float | Sequence[int | float] = 0, depth: Literal[8, 16, 32] = 8, **kwargs: Any) → Self

    Create a new PSD document.

    Parameters:

      - 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. Accepts a single integer (0-255 for 8-bit) or float in the [0.0, 1.0] range, or a sequence of per-channel values using the same ranges (e.g., 3 values for `"RGB"`, 4 for `"CMYK"`). Mixed int/float sequences are allowed. The color is used both as the initial image data fill and as the `background_color` compositing backdrop when saving.

      - depth – Bit depth (8, 16, or 32).

    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`

  property offset: tuple[int, int]

    (left, top) tuple.

    Returns:

      tuple

  classmethod open(fp: IO[bytes] | str | bytes | PathLike, max_alloc_bytes: int | None = None, **kwargs: Any) → Self

    Open a PSD document.

    Parameters:

      - fp – filename or file-like object.

      - max_alloc_bytes – optional per-document cap (bytes) on the buffer that `composite()`/`numpy()`/`topil()` allocate from the declared geometry; rendering raises `ValueError` if the estimate exceeds it. Defaults to the `$PSD_TOOLS_MAX_ALLOC_BYTES` env var (or `psd_tools.api.utils.MAX_ALLOC_BYTES`) when `None`.

      - 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

    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) → 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

  property right: int

    Right coordinate.

    Returns:

      int

  save(fp: IO[bytes] | str | bytes | PathLike, mode: str = 'wb', **kwargs: Any) → None

    Save the PSD file. Updates the ImageData section if the layer structure has been updated.

    Parameters:

      - 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 size: tuple[int, int]

    (width, height) tuple.

    Returns:

      tuple

  property tagged_blocks: TaggedBlocks | None

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

    See `psd_tools.constants.Tag` for available keys.

    Returns:

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

  property top: int

    Top coordinate.

    Returns:

      0

  topil(channel: int | ChannelID | None = None, apply_icc: bool = True) → Image | None

    Get PIL Image.

    Parameters:

      - channel – Which channel to return; e.g., 0 for ‘R’ channel in RGB image. See `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 version: int

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

    Returns:

      int

  property viewbox: tuple[int, int, int, int]

    Return bounding box of the viewport.

    Returns:

      (left, top, right, bottom) tuple.

  property visible: bool

    Visibility.

    Returns:

      True

  property width: int

    Document width.

    Returns:

      int

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