UnidentifiedImageError opening simple PSD using shapes and masks
What did you do?
Attempted to open the supplied psd image with PIL.open() in python.
I didn't actually create this image myself, nor can I figure out what exactly is wrong with it, but I've managed to reduce the cause of the issue down to 2 shape layers, one with a layer mask. Removing either layer fixes the error. Additionally, inserting a new empty layer between the two layers also fixes the error. So it's not critical and I can work around it, but I have a feeling it's a bug in the psd opening logic if it's somehow fixed by adding blank layers.
Image below of the layers:
What did you expect to happen?
No PIL.UnidentifiedImageError when opening the PSD.
What actually happened?
Received a PIL.UnidentifiedImageError when opening the PSD with PIL.open()
What are your OS, Python and Pillow versions?
- OS: MacOS Sonoma 14.4.1
- Python: 3.9.6 (via shim/pyenv)
- Pillow: 10.3.0 (via pip)
--------------------------------------------------------------------
Pillow 10.3.0
Python 3.9.6 (default, Apr 6 2024, 22:52:34)
[Clang 15.0.0 (clang-1500.3.9.4)]
--------------------------------------------------------------------
Python executable is /Users/<username>/.pyenv/versions/3.9.6/bin/python3
System Python files loaded from /Users/<username>/.pyenv/versions/3.9.6
--------------------------------------------------------------------
Python Pillow modules loaded from /Users/<username>/.pyenv/versions/3.9.6/lib/python3.9/site-packages/PIL
Binary Pillow modules loaded from /Users/<username>/.pyenv/versions/3.9.6/lib/python3.9/site-packages/PIL
--------------------------------------------------------------------
--- PIL CORE support ok, compiled for 10.3.0
--- TKINTER support ok, loaded 8.6
--- FREETYPE2 support ok, loaded 2.13.2
--- LITTLECMS2 support ok, loaded 2.16
--- WEBP support ok, loaded 1.3.2
--- WEBP Transparency support ok
--- WEBPMUX support ok
--- WEBP Animation support ok
--- JPEG support ok, compiled for libjpeg-turbo 3.0.2
--- OPENJPEG (JPEG2000) support ok, loaded 2.5.2
--- ZLIB (PNG/ZIP) support ok, loaded 1.3.1
--- LIBTIFF support ok, loaded 4.6.0
*** RAQM (Bidirectional Text) support not installed
*** LIBIMAGEQUANT (Quantization method) support not installed
--- XCB (X protocol) support ok
--------------------------------------------------------------------
Image is attached as zip because github doesn't allow psd attachments. ExamplePSD.psd.zip (29kb)
Code to reproduce (simple open PSD script):
import sys
import PIL
from PIL import Image
def open_psd(psd_file_path):
# Open the PSD file
psd_image = Image.open(psd_file_path)
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python3 piltest.py <input_psd_path>")
else:
psd_file_path = sys.argv[1]
open_psd(psd_file_path)
Removing either layer fixes the error. Additionally, inserting a new empty layer between the two layers also fixes the error.
Would it be an easy task for you to attach these variations as well for comparison?
No problem at all. Here's four variants. I've included in each zip a screen clipping of what the layers look like in photoshop. All the following .psd files open successfully with PIL.
ExamplePSDWithBottomLayerMaskRemoved.zip
ExamplePSDWithTopMostLayerRemoved.zip
So, the specification states that
If the compression code is 1, the image data starts with the byte counts for all the scan lines in the channel (LayerBottom-LayerTop)
and as far as I can see, the byte counts in the first image become incorrect at the end, or end prematurely.
However, your code is only trying to open the image. You are not trying to access the PSD layers. I have created #8039 to delay parsing the layers until the user needs Pillow to do so, and with that, your image can be opened successfully - you just can't extract the layers individually.
Would that be sufficient to resolve this, or do you think that the image is valid and further investigation should be done into reading the layers?
Apologies for the delay replying. Thanks for the fix! I do actually intend to access the layers later in my use case, so I'm not sure this fix is sufficient for my usage.
I'm pretty confident this image is valid, as I can open photoshop and create a similar image using the same layer format easily and get the same error. However I can easily fix these images by hand so any further fix is not urgently required.
If we were to figure out the error, then the 'blue 1' layer would be readable.
However, the 'blue' layer would still not be, as Pillow doesn't currently support reading layers with user supplied masks. If you're interested in accessing that as well, then this is a feature request - that doesn't change anything really, just letting you know it may be more difficult than you expected.
I appreciate this is probably quite tricky given the complexity of PSDs and layers.
I have done a bit of experimenting and realised that I am able to access the layer information by using a second library psd_tools which means the fix you've implemented so far does resolve the issue I was encountering. I can simply use Pillow to do the image conversion and psd_tools to access the layer information.
Thanks again for your help so far.
Pillow 10.4.0 has just been released with https://github.com/python-pillow/Pillow/pull/8039