Structure Description: LayeredFile#
The LayeredFile struct is the primary interface for editing Photoshop Files. It creates an abstraction over the actual implementation and provides more high level control over the Photoshop binary file format. It makes modifying a layer structure very convenient and as we are just shuffling pointers around internally also very efficient
Usage#
The code snippets below show some examples of how one would generally use a LayeredFile. For more detailed examples please visit Examples
using namespace NAMESPACE_PSAPI;
LayeredFile<bpp16_t> layeredFile = LayeredFile<bpp16_t>::read("InFile.psd");
// Move a layer one level up in the hierarchy
layeredFile.move_layer("Group/NestedGroup/Image", "Group");
// Delete the now empty group from the document
layeredFile.remove_layer("Group/NestedGroup");
// We can now convert the LayeredFile to a PhotoshopFile and write it out (this is done internally
// but can be exposed, see the ExtendedSignature example for more information)
LayeredFile<bpp16_t>::write(std::move(layeredFile), "OutFile.psd");
using namespace PhotoshopAPI;
const static uint32_t width = 64u;
const static uint32_t height = 64u;
LayeredFile<bpp8_t> document = { Enum::ColorMode::RGB, width, height };
// Create our individual channels to add to our image layer. Keep in mind that all these 3 channels
// need to be specified for RGB mode
std::unordered_map <Enum::ChannelID, std::vector<bpp8_t>> channelMap;
channelMap[Enum::ChannelID::Red] = std::vector<bpp8_t>(width * height, 255u);
channelMap[Enum::ChannelID::Green] = std::vector<bpp8_t>(width * height, 0u);
channelMap[Enum::ChannelID::Blue] = std::vector<bpp8_t>(width * height, 0u);
ImageLayer<bpp8_t>::Params layerParams = {};
layerParams.layerName = "Layer Red";
layerParams.width = width;
layerParams.height = height;
auto layer = std::make_shared<ImageLayer<bpp8_t>>(std::move(channelMap), layerParams);
document.add_layer(layer);
LayeredFile<bpp8_t>::write(std::move(layeredFile), "OutFile.psd");
Layer Type Derivatives#
Below you can find a list of layers that one is able to add to the LayeredFile instance.
Layer Types:
Global Data:
Conversion Functions#
-
template<typename T>
std::unique_ptr<PhotoshopFile> layered_to_photoshop(LayeredFile<T> &&layered_file, std::filesystem::path file_path)# Converts a layeredFile into a PhotoshopFile, taking ownership of and invalidating any data.
Note
This will not fill any specific TaggedBlocks or ResourceBlocks beyond what is required to create the layer structure.
Find Layer as specific type#
Finds a layer based on the given path and casts it to the given type.
This function matches LayeredFile<T>::find_layer() but instead of returning a generic layer basetype we return the requested type (if the cast is valid), this is especially useful if the layer type is known ahead of time and is the preferred way of accessing a layer.
Example call:
LayeredFile<bpp8_t> layeredFile{}; // We assume this is already populated auto imageLayerPtr = findLayerAs<bpp8_t, ImageLayer>("Path/To/ImageLayer", layeredFile);
The path should be separated by forward slashes, e.g., “Group1/GroupNested/ImageLayer”. Returns a reference to the specific layer if found; otherwise, returns nullptr and issues a warning. If we cannot upcast to the specified ptr a warning is raised and nullptr is returned.
- Parameters:
path – The path to the layer.
layeredFile – the file to search from
- Returns:
A shared pointer to the found layer or nullptr.
ICC Profile Struct#
-
struct ICCProfile#
Helper Structure for loading an ICC profile from memory of disk. Photoshop will then store the raw bytes of the ICC profile in their ICCProfile ResourceBlock (ID 1039)
Public Functions
-
inline ICCProfile()#
Initialize an empty ICCProfile.
-
inline ICCProfile(std::vector<uint8_t> data)#
Initialize the ICCProfile by passing in a raw byte array of an ICC profile.
-
ICCProfile(const std::filesystem::path &pathToICCFile)#
Initialize the ICCProfile by loading the path contents from disk.
-
inline std::vector<uint8_t> data() const noexcept#
Return a copy of the ICC profile data.
-
inline uint32_t data_size() const noexcept#
Return the absolute size of the data.
-
inline ICCProfile()#
LayeredFile Struct#
-
template<typename T>
struct LayeredFile# Represents a layered file structure.
This struct defines a layered file structure, where each file contains a hierarchy of layers. Layers can be grouped and organized within this structure.
- Template Parameters:
T – The data type used for pixel values in layers (e.g., uint8_t, uint16_t, float32_t).
Public Functions
-
inline ICCProfile icc_profile() const noexcept#
The files’ ICC Profile
The ICC Profile defines the view transform on the file but does not actually apply any color conversion. If you wish to actually convert your colors you should instead use something like
lcms2
-
inline void icc_profile(ICCProfile profile) noexcept#
-
inline float &dpi() noexcept#
The files’ dots per inch (dpi) resolution.
-
inline float dpi() const noexcept#
-
inline void dpi(float resolution)#
-
inline uint64_t &width() noexcept#
The files’ width from 1 - 300,000.
-
inline uint64_t width() const noexcept#
-
inline void width(uint64_t file_width)#
-
inline uint64_t &height() noexcept#
The files’ height from 1 - 300,000.
-
inline uint64_t height() const noexcept#
-
inline void height(uint64_t file_height)#
-
inline Geometry::BoundingBox<double> bbox() const noexcept#
Retrieve the bounding box describing the canvas, will always have a minimum of 0, 0.
-
inline Enum::ColorMode &colormode() noexcept#
The files’ colormode.
Currently we only fully support RGB, CMYK and Greyscale.
-
inline Enum::BitDepth bitdepth() const noexcept#
The files’ bitdepth.
As this is managed by the template type T we do not actually allow users to set this.
-
inline std::shared_ptr<LinkedLayers<T>> linked_layers() noexcept#
Primarily for internal use or advanced users. Users should usually not have to touch this as it’s handled for them by SmartObjects themselves
LinkedLayers describe a global state of linked files. Their purpose is to store the raw image data of smart objects such that any layer can have different resolution than the smart object and for deduplication.
-
LayeredFile() = default#
-
inline LayeredFile(std::unique_ptr<PhotoshopFile> file, std::filesystem::path file_path)#
Constructs a LayeredFile instance from a Photoshop file.
Takes ownership of the provided Photoshop file, transferring from a flat layer hierarchy to a layered file using the lrSectionDivider taggedBlock to identify layer breaks.
- Parameters:
file – The PhotoshopFile to transfer
file_path – The path to the photoshop file
-
inline LayeredFile(Enum::ColorMode colorMode, uint64_t width, uint64_t height)#
requires std Constructs an empty LayeredFile object.
Creates a LayeredFile with the specified color mode, width, and height.
Finds a layer based on the given path. The path should be separated by forward slashes, e.g., “Group1/GroupNested/ImageLayer”. Returns a reference to the specific layer if found; otherwise, returns nullptr and issues a warning.
Inserts a layer into the root of the layered file.
If you wish to add a layer to a group, use GroupLayer::addLayer() on a group node retrieved by \ref find_layer(). \param layer The layer to be added.
- Parameters:
colorMode – The color mode of the file.
width – The width of the file in pixels.
height – The height of the file in pixels.
path – The path to the layer.
- Returns:
A shared pointer to the found layer or nullptr.
Moves a layer from its current parent to a new parent node.
If no parentLayer is provided, moves the layer to the root. If the parentLayer is found to be under the layer it will issue a warning and stop the insertion. I.e. if moving “/Group” to “/Group/GroupNested/” that would be an illegal move operation as well as moving a layer to itself
- Parameters:
layer – The layer to be moved.
parentLayer – The new parent layer (if not provided, moves to the root).
-
inline void move_layer(const std::string layer, const std::string parentLayer = "")#
Moves a layer from its current parent to a new parent node.
If no parentLayer is provided, moves the layer to the root. If the parentLayer is found to be under the layer it will issue a warning and stop the insertion. I.e. if moving “/Group” to “/Group/GroupNested/” that would be an illegal move operation as well as moving a layer to itself
- Parameters:
layer – The layer to be moved.
parentLayer – The new parent layer (if not provided, moves to the root).
Recursively removes a layer from the layer structure.
Iterates the layer structure until the given node is found and then removes it from the tree.
- Parameters:
layer – The layer to be removed.
-
inline void remove_layer(const std::string layer)#
Recursively removes a layer from the layer structure.
Iterates the layer structure until the given node is found and then removes it from the tree.
- Parameters:
layer – The layer to be removed.
-
inline void set_compression(const Enum::Compression compCode)#
change the compression codec across all layers and channels
Iterates the layer structure and changes the compression codec for write on all layers. This is especially useful for e.g. 8-bit files which from Photoshop write with RLE compression but ZipCompression gives us better ratios
- Parameters:
compCode – the compression codec to apply
Generate a flat layer stack from either the current root or (if supplied) from the given layer. It should be preferred to use flat_layers() (no arguments) instead of this function.
- Parameters:
layer – Optional layer to start the generation from (default is root). If you provide e.g. a group this will only build the below layer tree
order – The order in which layers should be stacked.
- Returns:
The flat layer tree with automatic SectionDividerLayer inserted to mark section ends
-
inline std::vector<std::shared_ptr<Layer<T>>> flat_layers()#
Get a view over the flattened layer stack, helpful for iterating and applying properties to all layers such as visibility overrides etc.
After any layer modification actions this list may no longer be up-to-date so it would have to be re-generated. It is highly discouraged to use this flattened layer vector for any layer hierarchy modifications
- Returns:
The layer hierarchy as a flattened vector that can be iterated over.
-
inline uint16_t num_channels()#
Gets the total number of channels in the document.
- Returns:
The total number of channels in the document.
Checks if a layer already exists in the nested structure.
- Parameters:
layer – The layer to check for existence.
- Returns:
True if the layer exists, false otherwise.
Public Static Functions
-
static inline LayeredFile<T> read(const std::filesystem::path &filePath, ProgressCallback &callback)#
read and create a LayeredFile from disk
Simplify the creation of a LayeredFile by abstracting away the step of PhotoshopFile -> LayeredFile doing the work internally without exposing the PhotoshopFile instance to the user
- Parameters:
filePath – the path on disk of the file to be read
callback – the callback which reports back the current progress and task to the user
-
static inline LayeredFile<T> read(const std::filesystem::path &filePath)#
read and create a LayeredFile from disk
Simplify the creation of a LayeredFile by abstracting away the step of PhotoshopFile -> LayeredFile doing the work internally without exposing the PhotoshopFile instance to the user
- Parameters:
filePath – the path on disk of the file to be read
-
static inline void write(LayeredFile<T> &&layeredFile, const std::filesystem::path &filePath, ProgressCallback &callback, const bool forceOvewrite = true)#
write the LayeredFile instance to disk, consumes and invalidates the instance
Simplify the writing of a LayeredFile by abstracting away the step of LayeredFile -> PhotoshopFile doing the work internally without exposing the PhotoshopFile instance to the user
- Parameters:
layeredFile – The LayeredFile to consume, invalidates it
filePath – The path on disk of the file to be written
callback – the callback which reports back the current progress and task to the user
forceOvewrite – Whether to forcefully overwrite the file or fail if the file already exists
-
static inline void write(LayeredFile<T> &&layeredFile, const std::filesystem::path &filePath, const bool forceOvewrite = true)#
write the LayeredFile instance to disk, consumes and invalidates the instance
Simplify the writing of a LayeredFile by abstracting away the step of LayeredFile -> PhotoshopFile doing the work internally without exposing the PhotoshopFile instance to the user
- Parameters:
layeredFile – The LayeredFile to consume, invalidates it
filePath – The path on disk of the file to be written
forceOvewrite – Whether to forcefully overwrite the file or fail if the file already exists
Layer Order Enum#
-
enum class LayerOrder#
Enumerator to specify the order of traversal for parsing.
Values:
-
enumerator forward#
Forward in this case refers to us going top to bottom. e.g. if we have the layer structure
We would write out the layers starting with ‘Group’Group NestedGroup Image
-
enumerator reverse#
Reverse in this case refers to us going bottom to top. e.g. if we have the layer structure
We would write out the layers starting with ‘Image’Group NestedGroup Image
-
enumerator forward#