Releases: EmilDohne/PhotoshopAPI
v0.9.0
This release primarily brings the long awaited support for editable text layers thanks to @ogkalu2!. For documentation please refer to here:
https://photoshopapi.readthedocs.io/en/latest/concepts/text-layers.html
Features:
- Add support for editable text layer. You can now read/parse/update/create text layer data.
- Add support for modifying a layers' display color via the new
Layer<T>::display_colorproperty. - Add support for passing unparsed data on roundtripping so e.g. adjustment layers will be maintained as you read/write files.
Bugfixes
- Fix linked layers from latest photoshop release not parsing due to updated descriptor version (thanks @prodBirdy!)
CI/Build
- Add support for python 3.14 out of the box
v0.8.2
v0.8.1
v0.8.0
This release mainly focuses on bugfixes as well as some QOL changes. More larger changes are to follow!
We have a first time contribute with this release @oallw, thank you for contributing! 🥳
Features:
- Swap the internal compression backend to use the compressed-image API which should give some additional performance/memory savings as well as providing a way to interact with the compressed file buffers.
- python: Allow setting of icc profiles directly with numpy arrays
Bugfixes
- Fix various Unicode related issues related to file reads. This should now be much more consistent #180 #182
- python: Fix bug where unicode assignment was broken #174 from @oallw
- Fix issue where after replacing a SmartObject, the warp/transform was lost #162
CI/Build
- Fix vcpkg binary caching to speed up CI/Releases
- Bump OpenImageIO from 2.5.16.0 -> 3.0.9.1
v0.7.0 - Smart Object improvements
The v0.7.0 Release primarily fixes miscellaneous errors on smart objects as well as exposing the clipping mask property on layers
Note
This release changes the python import of psapi -> photoshopapi. If you wish to keep using psapi as alias you can import photoshopapi as psapi
Features:
- Add the
clipping_maskfield to all layer types, allowing you to set and restore clipping masks. #156
Bugfixes
- Fix issue with smart object layers where the quilt warp was being calculated incorrectly, causing stepped output files with an offset #156
- Fix miscellaneous read errors when attempting to read older style smart object descriptors.
photoshopapipython package will now be properly installed intophotoshopapiandphotoshopapi.libsrather than pollutingsite-packages- Fix python issue on windows where you weren't able to import both PhotoshopAPI and OpenImageIO due to dll issues.
CI/Build
- Change python wheel setup to use more modern
scikit-build-core. Deprecate the oldsetup.pyworkflow completely replacing it with a much simplerpyproject.toml
Breaking Changes:
- The python wheels are now importable via
import photoshopapi, notimport psapi
v0.6.1
The v0.6.1 Release fixes some bugs related to smart object layer parsing
Warning
This release drops support for python 3.7 wheels due to CI limitations
Bugfixes:
- Fix smart object layer translating to 0,0 on write #142
- Fix incorrect padding for
LinkedLayerItemsometimes causing files with more than one smart object layer to fail #149 - Add internal mini psd/psb reader for reading embedded photoshop files in smart objects rather than relying on OpenImageIO #149
- Add handling and tests for smart object layers that do not embed the
customEnvelopeWarpfield (which seems to happen sometimes) #149
Deprecations
- Deprecate
SmartObjectWarp::valid().
v0.6.0 - Smart Objects
The v0.6.0 Release primarily targets adding support for SmartObject layers and warps. Additionally, we refactored large parts of the internal and public API.
To check out how to use SmartObjects please have a look here for an example, here for the documentation (c++) and here for the documentation (python)
Warning
This is a breaking release, please proceed with caution and read both the changelogs and documentation carefully as large parts of the API were overhauled.
Features:
- Add support for SmartObject layers
SmartObjectLayer<T>,psapi.SmartObjectLayer_*bit - add support for SmartObject warps (Exceptions being "smart" perspective warp and puppet warp)
Python
- Expose all mask parameters that were previously hidden. This includes
mask_disabled,mask_relative_to_layer,mask_default_color,mask_density,mask_feather,mask_position,mask_widthandmask_height
Bugfixes:
- Masks on layers now are better supported and have their width and height decoupled from the layers' width and height (except for during construction of image layers).
- Internal: Harden file section write to be less error prone using scoped section markers
C++
- Harden template requirements to only allow
uint8_t,uint16_t,floatfor all Photoshop related templates
Python
- Add missing
is_visibleandis_lockedarguments to constructor of layers
Breaking Changes:
- Layer coordinates are no longer expressed relative to the canvas center but rather relative to canvas top left to be more in line with photoshop
- Example: if previously for a 64x64 canvas a centered layer was at (0, 0), now it would be at (32, 32)
- Layer opacity is now expressed as a float (but still backed by a
uint8_t
C++
- Drop C++17 support
- Public facing API was changed from
camelCasetosnake_caseto be more in line and equal to python bindings - All previously public member variables are now private with appropriate getters and setters to allow the API to implement more logic on them in the future
Python
- All image data is no longer expressed as a property but instead as method as these are potentially quite expensive to compute
ImageLayer_*bit.channelsproperty is nowImageLayer_*bit.channel_indices()
Miscellaneous:
- Add Compositing Framework to prepare for eventual layer stack compositing
- Internal: Add basic 2D rendering framework
- Internal: Add Geometry Framework to allow for parsing of Quad Meshes and Bezier Surfaces
- Internal: Add Parsing of Descriptors
- Internal: Simplify endian functions to work more generically
- Refactor large parts of the internal API.
- Refactor inheritance structure of Image Based layers and extract mask logic to mixin
Dependencies:
- Add
OpenImageIOas dependency (via vcpkg) - Add
fmtas dependency (via vcpkg) - Add
stduiidas dependency (via vcpkg) - Add
eigen3as dependency (via vcpkg) - Add
jsonas a submodule - Move
libdeflatefrom submodule to vcpkg - Add
vcpkgsubmodule - Bump c-blosc2 to 2.15.2
Documentation
- Link in examples directly to hosted docs for easier access
CI:
- Add Clang ubuntu build target
- Add ASAN to all tests (that support it)
- Add Clang ubuntu valgrind target
v0.5.2
Bugfixes
Python
- When calling
ImageLayer.get_image_data()orImageLayer.image_datait no longer fails if there is a mask channel with a different size than the image data itself ImageLayernum_channelsandchannelsproperties now consider the mask channel instead of skipping it
v0.5.1
v0.5.0
The v0.5.0 Release primarily targets adding support for CMYK and Grayscale while also improving the overal consistency of the python bindings. Additionally we added support for trivially replacing image data.
Three new examples were added. Please feel free to check them out!
- Using Progress callbacks (C++ only for now)
- Replacing image data on a layer
- Rescaling a whole file using OpenCV
Roadmap
v0.6.0
- Adjustment Layers
- Smart Objects
Performance
- Read and Write speeds of 8-bit files are about 30-40% faster
- Read and Write speeds of 16- and 32-bit files are about 10-15% faster
- Image data extraction from
ImageLayer<T>now runs fully parallelized - Python channel extraction speed was greatly improved
Features:
C++ / General
- Add optional
ProgressCallbackthat can be passed to read and write functions forLayeredFile<T> - Add support for Unicode layer names. Preferring these over PascalString layer names.
- Add support for CMYK color mode
- Add support for Grayscale color mode
- Make files Krita compatible
- Add support for locked layers
- Add a
PhotoshopFile::findBitdepth()function which reads out the header and allows for programmatic dispatching ofLayeredFile<T>instances - Add a
LayeredFile<T>::flatLayers()function for getting a flattened layer hierarchy which can be iterated without recursion. - Add functions for swapping image data:
ImageLayer<T>::setImageData(),Layer<T>::setMask()
Python
- Added more verbose error logging if the image data provided as numpy array does not match what is expected
- LayeredFile: add
flat_layersproperty giving you a temporary view over all the layers allowing for easy flat traversal. This is especially useful when applying some operation to all layers like resizing. - Layer: add
is_visibleproperty - Layer: add
is_lockedproperty - Layer: add
has_mask()function - ImageLayer: add
set_image_data,set_channel_by_idandset_channel_by_indexfunctions as well as making theimage_dataproperty read-writable - ImageLayer: add
num_channelsandchannelsproperties
Bugfixes:
C++ / General
findLayerAs()function no longer raises an error if layer cannot be found but instead returnsnullptrto be more consistent withLayeredFile<T>::findLayer()- Fix memory leak due to missing call to
blosc2_schunk_free() - Fix bug where files with only GroupLayers would not be openable in photoshop
- Mask channels passed to
ImageLayer<T>as image data now get automatically forwarded tom_LayerMask
Python
- Fixed bug where non c-style contiguous arrays wouldn't be parsed correctly (e.g. when using
numpy.reshape()). This conversion is now forced in-place - Fix missing
selfargument in psapi-stubs
Deprecations
- Deprecate
Layer<T>::getMaskData()in favour ofLayer<T>::getMask()
Breaking changes:
The main breaking changes are to what is considered the internal API. A lot of the files in Util/ were moved over to Core/ where appropriate.
ImageLayer<T> constructor now takes an int16_t rather than uint16_t
Python
- The
Layer.layer_maskproperty has been removed in favour ofLayer.mask. This property is now read-writable
CI / Compiling
- Cranked up warnings under MSVC to /W4 and /WX with some additional warnings
- Added ASAN and Valgrind steps to CI for continuous checking of correctness
- Added memory-mapped files as backend for faster load times