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 the PhotoshopExamples/ directory on the github page
using namespace NAMESPACE_PSAPI;
LayeredFile<bpp16_t> layeredFile = LayeredFile<bpp16_t>::read("InFile.psd");
// Move a layer one level up in the hierarchy
layeredFile.moveLayer("Group/NestedGroup/Image", "Group");
// Delete the now empty group from the document
layeredFile.removeLayer("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.addLayer(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. Keep in mind that some of these are not fully implemented yet
Conversion Functions#
-
template<typename T>
std::unique_ptr<PhotoshopFile> LayeredToPhotoshopFile(LayeredFile<T> &&layeredFile)# 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>::findLayer() 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 an error is raised.
- 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> getData() const noexcept#
Return a copy of the ICC profile data.
-
inline uint32_t getDataSize() 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
-
LayeredFile(std::unique_ptr<PhotoshopFile> file)#
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
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 findLayer().
- Parameters:
layer – The layer to be added.
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).
-
void moveLayer(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.
-
void removeLayer(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.
-
void setCompression(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
Generates a flat layer stack from either the current root or a given layer.
Generate a flat layer stack from either the current root or (if supplied) from the given layer. Use this function if you wish to get the most up to date flat layer stack that is in the given
Use this function to get the most up-to-date flat layer stack based on the given order.
- Parameters:
layer – Optional layer to start the generation from (default is root).
order – The order in which layers should be stacked.
- Returns:
The flat layer tree with automatic SectionDividerLayer inserted to mark section ends
-
uint16_t getNumChannels(bool ignoreMaskChannels = true, bool ignoreAlphaChannel = true)#
Gets the total number of channels in the document.
Excludes mask channels unless ignoreMaskChannels is set to false. Same goes for ignoreAlphaChannel
- Parameters:
ignoreMaskChannels – Flag to exclude mask channels from the count.
ignoreMaskChannel – Flag to exclude the transparency alpha channel from the count.
- 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 Members
-
std::vector<std::shared_ptr<Layer<T>>> m_Layers#
The root layers in the file, they may contain multiple levels of sub-layers.
-
ICCProfile m_ICCProfile#
The ICC Profile associated with the file, this may be empty in which case there will be no colour profile associated with the file
-
float m_DotsPerInch = 72.0f#
The DPI of the document, this will only change the display unit and wont resize any data.
-
Enum::ColorMode m_ColorMode = Enum::ColorMode::RGB#
The color mode of the file. Currently supports RGB only.
-
uint64_t m_Width = 0u#
The width of the file in pixels. Can be up to 30,000 for PSD and up to 300,000 for PSB.
-
uint64_t m_Height = 0u#
The height of the file in pixels. Can be up to 30,000 for PSD and up to 300,000 for PSB.
Public Static Functions
-
static 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 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#