@@ -45,33 +45,31 @@ Features
45
45
=========
46
46
47
47
Supported:
48
- - Read and write of \* .psd and \* .psb files
49
- - Creating and modifying simple and complex nested layer structures
50
- - Pixel Masks
51
- - Modifying layer attributes (name, blend mode, image data etc.)
52
- - Setting the Display ICC Profile
53
- - Setting the DPI of the document
54
- - 8-, 16- and 32-bit files
55
- - RGB, CMYK and Grayscale color modes
56
- - All compression modes known to Photoshop
48
+ - Read and write of \* .psd and \* .psb files
49
+ - Creating and modifying simple and complex nested layer structures
50
+ - Smart Objects (replacing, warping, extracting)
51
+ - Pixel Masks
52
+ - Modifying layer attributes (name, blend mode etc.)
53
+ - Setting the Display ICC Profile
54
+ - 8-, 16- and 32-bit files
55
+ - RGB, CMYK and Grayscale color modes
56
+ - All compression modes known to Photoshop
57
57
58
58
Planned:
59
- - Support for Adjustment Layers (planned ` v0.6.0 ` )
60
- - Support for Vector Masks
61
- - Support for Text Layers
62
- - Support for Smart Object Layers (planned ` v0.6.0 ` )
63
- - Indexed and Duotone Color Modes
59
+ - Support for Adjustment Layers
60
+ - Support for Vector Masks
61
+ - Support for Text Layers
62
+ - Indexed, Duotone Color Modes
64
63
65
64
Not Supported:
66
- - Files written by the PhotoshopAPI do not contain a valid merged image in order to save size meaning they will not behave properly when opened in
67
- third party apps requiring these (such as Lightroom)
68
- - Lab and Multichannel Color Modes
69
-
65
+ - Files written by the PhotoshopAPI do not contain a valid merged image in order to save size meaning they will not behave properly when opened in
66
+ third party apps requiring these (such as Lightroom)
67
+ - Lab and Multichannel Color Modes
70
68
71
69
Python
72
70
==============
73
71
74
- The PhotoshopAPI comes with fully fledged Python bindings which can be simply installed using
72
+ The PhotoshopAPI comes with Python bindings which can be installed using
75
73
```
76
74
$ py -m pip install PhotoshopAPI
77
75
```
@@ -134,77 +132,65 @@ Below is a minimal example to get started with opening a PhotoshopFile, removing
134
132
### C++
135
133
136
134
``` cpp
137
- using namespace PhotoshopAPI ;
138
-
139
- // Initialize an 8-bit layeredFile. This must match the bit depth of the PhotoshopFile.
140
- // To initialize this programmatically please refer to the ExtendedSignature example
141
- LayeredFile<bpp8_t > layeredFile = LayeredFile<bpp8_t >::read(" InputFile.psd" );
142
-
143
- // Do some operation, in this case delete
144
- layeredFile.removeLayer(" SomeGroup/SomeNestedLayer" );
145
-
146
- // One could write out to .psb instead if wanted and the PhotoshopAPI will take
147
- // care of any conversion internally
148
- LayeredFile<bpp8_t >::write(std::move(layeredFile), " OutputFile.psd" );
135
+ using namespace NAMESPACE_PSAPI ;
136
+
137
+ // Initialize some constants that we will need throughout the program
138
+ const static uint32_t width = 64u ;
139
+ const static uint32_t height = 64u ;
140
+
141
+ // Create an 8-bit LayeredFile as our starting point, 8- 16- and 32-bit are fully supported
142
+ LayeredFile<bpp8_t > document = { Enum::ColorMode::RGB, width, height };
143
+ // Create our individual channels to add to our image layer. Keep in mind that all these 3 channels need to
144
+ // be specified for RGB mode
145
+ std::unordered_map <Enum::ChannelID, std::vector<bpp8_t>> channelMap;
146
+ channelMap[ Enum::ChannelID::Red] = std::vector<bpp8_t>(width * height, 255u);
147
+ channelMap[ Enum::ChannelID::Green] = std::vector<bpp8_t>(width * height, 0u);
148
+ channelMap[ Enum::ChannelID::Blue] = std::vector<bpp8_t>(width * height, 0u);
149
+
150
+ ImageLayer<bpp8_t>::Params layerParams = {};
151
+ layerParams.name = "Layer Red";
152
+ layerParams.width = width;
153
+ layerParams.height = height;
154
+
155
+ auto layer = std::make_shared<ImageLayer<bpp8_t>>(std::move(channelMap), layerParams);
156
+ document.add_layer(layer);
157
+
158
+ // It is perfectly legal to modify a layers properties even after it was added to the document as attributes
159
+ // are only finalized on export
160
+ layer->opacity(.5f);
161
+
162
+ // Convert to PhotoshopFile and write to disk. Note that from this point onwards
163
+ // our LayeredFile instance is no longer usable
164
+ LayeredFile<bpp8_t>::write(std::move(document), "WriteSimpleFile.psd");
149
165
```
150
166
151
167
152
- The same code for reading and writing can also be used to for example ` LayeredFile::moveLayer ` or ` LayeredFile::addLayer ` as well as extracting any image data
168
+ The same code for reading and writing can also be used to for example `LayeredFile::move_layer_ ` or `LayeredFile::add_layer ` as well as extracting any image data
153
169
154
170
### Python
155
171
156
172
```py
173
+ import os
174
+ import numpy as np
157
175
import psapi
158
176
159
- # Read the layered_file using the LayeredFile helper class, this returns a
160
- # psapi.LayeredFile_*bit object with the appropriate bit-depth
161
- layered_file = psapi.LayeredFile.read(" InputFile.psd" )
162
-
163
- # Do some operation, in this case delete
164
- layered_file.remove_layer()
177
+ # Initialize some constants that we will need throughout the program
178
+ width = 64
179
+ height = 64
180
+ color_mode = psapi.enum.ColorMode.rgb
165
181
166
- # Write back out to disk
167
- layered_file.write(" OutFile.psd" )
168
- ```
182
+ # Generate our LayeredFile instance
183
+ document = psapi.LayeredFile_8bit(color_mode, width, height)
169
184
170
- We can also do much more advanced things such as taking image data from one file and transferring
171
- it to another file, this can be across file sizes, psd/psb and even bit-depth!
172
-
173
- ``` py
174
- import psapi
175
- import numpy as np
176
- import os
185
+ img_data = np.zeros((3, height, width), np.uint8)
186
+ img_data[0] = 255
187
+ # When creating an image layer the width and height parameter are required if its not a zero sized layer
188
+ img_layer = psapi.ImageLayer_8bit(img_data, "Layer Red", width=width, height=height)
189
+ document.add_layer(img_layer)
177
190
191
+ # Similar to the C++ version we can adjust parameters of the layer after it has been added to the document
192
+ # as long as it happens before we write to disk
193
+ img_layer.opacity = .5
178
194
179
- def main () -> None :
180
- # Read both our files, they can be open at the same time or we can also read one file,
181
- # extract the layer and return just that layer if we want to save on RAM.
182
- file_src = psapi.LayeredFile.read(" GraftSource_16.psb" )
183
- file_dest = psapi.LayeredFile.read(" GraftDestination_8.psd" )
184
-
185
- # Extract the image data and convert to 8-bit.
186
- lr_src: psapi.ImageLayer_16bit = file_src[" GraftSource" ]
187
- img_data_src = lr_src.get_image_data()
188
- img_data_8bit = {}
189
- for key, value in img_data_src.items():
190
- value = value / 256 # Convert from 0-65535 -> 0-255
191
- img_data_8bit[key] = value.astype(np.uint8)
192
-
193
- # Reconstruct an 8bit converted layer
194
- img_layer_8bit = psapi.ImageLayer_8bit(
195
- img_data_8bit,
196
- layer_name = lr_src.name,
197
- width = lr_src.width,
198
- height = lr_src.height,
199
- blend_mode = lr_src.blend_mode,
200
- opacity = lr_src.opacity
201
- )
202
-
203
- # add the layer and write out to file!
204
- file_dest.add_layer(img_layer_8bit)
205
- file_dest.write(" GraftDestination_8_Edited.psd" )
206
-
207
-
208
- if __name__ == " __main__" :
209
- main()
210
- ```
195
+ document.write(os.path.join(os.path.dirname(__file__), "WriteSimpleFile.psd"))
196
+ ```
0 commit comments