LayeredFile#
About#
The LayeredFile class is the main class for interacting with photoshop files as it abstracts away
the implementation of the underlying data structures and provides a simple to use interface over
a generic image file with layers. Below we only document the LayeredFile_8bit as well as the helper class
for construction LayeredFile but there is one class for each bit-depth noted in photoshopapi.enum.BitDepth
(LayeredFile_16bit and LayeredFile_32bit respectively).
The function signature for all of these is the same as with the 8-bit instance.
To get started with using the LayeredFile instance for reading/writing files check the two methods below. The “Simple” example allows for the reading of a LayeredFile with a single line of code and will return one of the three bit depths types for files.
The “Extended” example on the other hand shows essentially what the LayeredFile.read() method is doing under the hood.
import photoshopapi as psapi
file_path = "Path/To/File.psb"
# This is a wrapper over the different LayeredFile_*bit types and will actually return the
# appropriate type depending on the file itself
layered_file = photoshopapi.LayeredFile.read(file_path)
# it is however important to note that the layered_file variable will be one of 3 types
# LayeredFile_8bit | LayeredFile_16bit | LayeredFile_32bit
# modify the layered_file...
layered_file.write("Path/To/Out.psb")
import photoshopapi as psapi
file_path = "Path/To/File.psb"
bit_depth: photoshopapi.enum.BitDepth = photoshopapi.PhotoshopFile.find_bitdepth(file_path)
layered_file = None
if bit_depth == photoshopapi.enum.BitDepth.bd_8:
layered_file = photoshopapi.LayeredFile_8bit.read(file_path)
elif bit_depth == photoshopapi.enum.BitDepth.bd_16:
layered_file = photoshopapi.LayeredFile_16bit.read(file_path)
elif bit_depth == photoshopapi.enum.BitDepth.bd_32:
layered_file = photoshopapi.LayeredFile_32bit.read(file_path)
if not layered_file:
raise RuntimeError("Unable to deduce LayeredFile bit-depth")
# modify the layered_file...
layered_file.write("Path/To/Out.psb")
The reasoning behind the LayeredFile being split up between bit-depths is due to the templated
nature of the C++ classes. We try to provide convenience wrappers such as photoshopapi.LayeredFile to
simplify the usage and typing of these as much as possible
Layer Type Derivatives#
Below you can find a list of layers that one is able to add to the LayeredFile instance.
Layer Types:
Class Reference LayeredFile#
- class photoshopapi.LayeredFile#
A wrapper class for the different LayeredFile subtypes that we can call read() on to return the appropriate LayeredFile instance.
Warning
The psapi.LayeredFile class’ only job is to simplify the read of a LayeredFile_*bit from disk with automatic type deduction. It does not however hold any of the data itself.
- static read(path: os.PathLike) photoshopapi.lib64.photoshopapi.LayeredFile_8bit | photoshopapi.lib64.photoshopapi.LayeredFile_16bit | photoshopapi.lib64.photoshopapi.LayeredFile_32bit#
Read a layeredfile into the appropriate type based on the actual bit-depth of the document
- Parameters:
path (str) – The path to the Photoshop file
- Return type:
psapi.LayeredFile_8bit|psapi.LayeredFile_16bit|psapi.LayeredFile_32bit
- class photoshopapi.LayeredFile_8bit#
This class defines a layered file structure, where each file contains a hierarchy of layers. Layers can be grouped and organized within this structure.
- Attributes:
- iccnumpy.ndarray
Property for setting and retrieving the ICC profile attached to the file. This does not do any color conversions but simply tells photoshop how to interpret the data. The assignment is overloaded such that you need to pass a path to the ICC file you want to load and loading will be done internally.
- compressionpsapi.enum.Compression
Write-only property which sets the compression of all the layers in the LayeredFile
- num_channelsint
Read-only property to retrieve the number of channels from the file (excludes mask channels)
- bit_depthpsapi.enum.BitDepth
Read-only property to retrieve the bit-depth
- layerslist[Layer_*bit]
Read-only property to retrieve a list of all the layers in the root of the file
- flat_layers: list[Layer_*bit]
Read-only property to retrieve a flat list of all the layers in the file, convenience function for iterating them all at once. Do not attempt to modify the layer structure itself while iterating over this flattened layer list as this wil lead to undefined behaviour
- dpiint
The document DPI settings
- widthint
The width of the document, must not exceed 30,000 for PSD or 300,000 for PSB
- heightint
The height of the document, must not exceed 30,000 for PSD or 300,000 for PSB
- __getitem__(self: photoshopapi.lib64.photoshopapi.LayeredFile_8bit, name: str) photoshopapi.lib64.photoshopapi.Layer_8bit#
Get the specified layer from the root of the layered file. Unlike
find_layer()this does not accept a path but rather a single layer located in the root layer. This is to make chaining of paths more pythonic since group layers also implement a __getitem__ functionlayered_file: LayeredFile_*bit = # Our layered file instance nested_img_layer = layered_file["Group"]["Image"]
- Parameters:
name (str) – The name of the layer to search for
- Raises:
KeyError: If the requested layer is not found
- Returns:
The requested layer instance
- add_layer(self: photoshopapi.lib64.photoshopapi.LayeredFile_8bit, layer: photoshopapi.lib64.photoshopapi.Layer_8bit) None#
- find_layer(self: photoshopapi.lib64.photoshopapi.LayeredFile_8bit, path: str) photoshopapi.lib64.photoshopapi.Layer_8bit#
Find a layer based on the given path
- Parameters:
path (str) – The path to the requested layer
- Returns:
The requested layer
- Raises:
ValueError: If the path is not a valid path to a layer
- invalidate_text_cache(self: photoshopapi.lib64.photoshopapi.LayeredFile_8bit) None#
Remove the global Txt2 block and mark all text layers dirty so Photoshop re-renders every one on open.
What this does (two steps):
Strips the global
Txt2(TextEngineData) tagged block. Photoshop uses this block as a render-cache token; its absence causes the “Update text layers?” dialog to appear the moment the file is opened.Forces every text layer through the parsed TySh serialization path. Without this step, layers never touched by setter APIs stay as raw-byte pass-throughs; Photoshop’s per-layer update checker sees no change in their data and silently skips re-rendering them, leaving them blank even after you click Update.
After one click of “Update” in Photoshop, all text layers are rendered from the live TySh metadata and remain fully editable. The actual text content and styling of unmodified layers is preserved exactly.
Example usage:
lf = psapi.LayeredFile.read("template.psd") # ... edit specific text layers ... lf.invalidate_text_cache() # one call - all layers will render on open lf.write("output.psd")
- is_layer_in_document(self: photoshopapi.lib64.photoshopapi.LayeredFile_8bit, layer: photoshopapi.lib64.photoshopapi.Layer_8bit) bool#
Check if the layer already exists in the LayeredFile at any level of nesting, this check is done internally on add_layer().
- move_layer(*args, **kwargs)#
Overloaded function.
move_layer(self: photoshopapi.lib64.photoshopapi.LayeredFile_8bit, child: photoshopapi.lib64.photoshopapi.Layer_8bit, parent: photoshopapi.lib64.photoshopapi.Layer_8bit = None) -> None
Move the child layer to the provided parent layer, if none is provided we move to scene root instead
move_layer(self: photoshopapi.lib64.photoshopapi.LayeredFile_8bit, child: str, parent: str = ‘’) -> None
- static read(path: os.PathLike) photoshopapi.lib64.photoshopapi.LayeredFile_8bit#
Read and create a LayeredFile from disk. If the bit depth isnt known ahead of time use LayeredFile.read() instead which will return the appropriate type
- remove_layer(*args, **kwargs)#
Overloaded function.
remove_layer(self: photoshopapi.lib64.photoshopapi.LayeredFile_8bit, layer: photoshopapi.lib64.photoshopapi.Layer_8bit) -> None
Remove the specified layer from root of the layered_file, if you instead wish to remove from a group call remove_layer on a GroupLayer_*bit instance instead
remove_layer(self: photoshopapi.lib64.photoshopapi.LayeredFile_8bit, layer: str) -> None
- write(self: photoshopapi.lib64.photoshopapi.LayeredFile_8bit, path: os.PathLike, force_overwrite: bool = True) None#
Write the LayeredFile_*bit instance to disk invalidating the data, after this point trying to use the instance is undefined behaviour.
- Parameters:
path (os.PathLike) – The path of the output file, must have a .psd or .psb extension. Conversion between these two types is taken care of internally
force_overwrite (bool) – Defaults to True, whether to forcefully overwrite the file if it exists. if False the write-op fails and emits an error message