Image.open gives error Cannot identify image file

21,986

Solution 1

You have a multi-channel 32-bit TIFF image, and Pillow doesn't yet support that format. See issue #1888:

Pillow (and PIL) is currently able to open 8 bit per channel multi-channel images (such as RGB) but is able to open higher bit depth images (e.g. I16, I32, or Float32 images) if they are single channel (e.g., grayscale).

[...]

Requirements

  • We should be able to support common GIS formats as well as high bit depth RGB(A) images.
  • At least 4 channels, but potentially more (see #1839)
  • Different pixel formats, including I16, I32, and Float.

I determined this by using the TIFF plugin image reader directly, with debug mode enabled:

from PIL import TiffImagePlugin
TiffImagePlugin.DEBUG = True
with open(image_path, 'rb') as f:
    TiffImagePlugin.TiffImageFile(f)

which includes the output:

tag: BitsPerSample (258) - type: short (3) Tag Location: 46 - Data Location: 218 - value: (32, 32, 32)

(full debug output below)

You can use the Python GDAL bindings to read this format. You can also use the gdal_translate command line utility to convert your files to a format that Pillow can handle; for multiband, you'd have to go down to 8 bits, or move to grayscale.

For example, to translate your input file to PNG, you can use:

gdal_translate -of PNG rgb_CGI.tiff rgb_CGI.png

after which Pillow can open the PNG file.


Full debug output from Pillow's TIFF plugin:

>>> from PIL import TiffImagePlugin
>>> TiffImagePlugin.DEBUG = True
>>> with open(image_path, 'rb') as f:
...     TiffImagePlugin.TiffImageFile(f)
...
*** TiffImageFile._open ***
- __first: 8
- ifh:  b'II*\x00\x08\x00\x00\x00'
Seeking to frame 0, on frame -1, __next 8, location: 8
Loading tags, location: 8
tag: ImageWidth (256) - type: short (3) - value: 2924
tag: ImageLength (257) - type: short (3) - value: 2088
tag: BitsPerSample (258) - type: short (3) Tag Location: 46 - Data Location: 218 - value: (32, 32, 32)
tag: Compression (259) - type: short (3) - value: 1
tag: PhotometricInterpretation (262) - type: short (3) - value: 1
tag: StripOffsets (273) - type: long (4) Tag Location: 82 - Data Location: 8576 - value: <table: 8352 bytes>
tag: SamplesPerPixel (277) - type: short (3) - value: 3
tag: RowsPerStrip (278) - type: short (3) - value: 1
tag: StripByteCounts (279) - type: long (4) Tag Location: 118 - Data Location: 224 - value: <table: 8352 bytes>
tag: PlanarConfiguration (284) - type: short (3) - value: 1
tag: ExtraSamples (338) - type: short (3) - value: (0, 0)
tag: SampleFormat (339) - type: short (3) Tag Location: 154 - Data Location: 16928 - value: (2, 2, 2)
tag: ModelPixelScaleTag (33550) - type: double (12) Tag Location: 166 - Data Location: 16934 - value: (0.25, 0.25, 0.0)
tag: ModelTiepointTag (33922) - type: double (12) Tag Location: 178 - Data Location: 16958 - value: <table: 48 bytes>
tag: GeoKeyDirectoryTag (34735) - type: short (3) Tag Location: 190 - Data Location: 17006 - value: <table: 72 bytes>
tag: GeoDoubleParamsTag (34736) - type: double (12) Tag Location: 202 - Data Location: 17078 - value: <table: 56 bytes>
tag: GeoAsciiParamsTag (34737) - type: string (2) Tag Location: 214 - Data Location: 17134 - value: Amersfoort / RD New|Amersfoort|
tag: ImageWidth (256) - type: short (3) - value: 2924
tag: ImageLength (257) - type: short (3) - value: 2088
tag: BitsPerSample (258) - type: short (3) Tag Location: 46 - Data Location: 218 - value: (32, 32, 32)
tag: Compression (259) - type: short (3) - value: 1
tag: PhotometricInterpretation (262) - type: short (3) - value: 1
tag: StripOffsets (273) - type: long (4) Tag Location: 82 - Data Location: 8576 - value: <table: 8352 bytes>
tag: SamplesPerPixel (277) - type: short (3) - value: 3
tag: RowsPerStrip (278) - type: short (3) - value: 1
tag: StripByteCounts (279) - type: long (4) Tag Location: 118 - Data Location: 224 - value: <table: 8352 bytes>
tag: PlanarConfiguration (284) - type: short (3) - value: 1
tag: ExtraSamples (338) - type: short (3) - value: (0, 0)
tag: SampleFormat (339) - type: short (3) Tag Location: 154 - Data Location: 16928 - value: (2, 2, 2)
tag: ModelPixelScaleTag (33550) - type: double (12) Tag Location: 166 - Data Location: 16934 - value: (0.25, 0.25, 0.0)
tag: ModelTiepointTag (33922) - type: double (12) Tag Location: 178 - Data Location: 16958 - value: <table: 48 bytes>
tag: GeoKeyDirectoryTag (34735) - type: short (3) Tag Location: 190 - Data Location: 17006 - value: <table: 72 bytes>
tag: GeoDoubleParamsTag (34736) - type: double (12) Tag Location: 202 - Data Location: 17078 - value: <table: 56 bytes>
tag: GeoAsciiParamsTag (34737) - type: string (2) Tag Location: 214 - Data Location: 17134 - value: Amersfoort / RD New|Amersfoort|
*** Summary ***
- compression: raw
- photometric_interpretation: 1
- planar_configuration: 1
- fill_order: 1
- size: (2924, 2088)
format key: (b'II', 1, (2, 2, 2), 1, (32, 32, 32), (0, 0))
- unsupported format
Traceback (most recent call last):
  File "/Users/mjpieters/Development/venvs/stackoverflow-3.6/lib/python3.6/site-packages/PIL/TiffImagePlugin.py", line 1196, in _setup
    self.mode, rawmode = OPEN_INFO[key]
KeyError: (b'II', 1, (2, 2, 2), 1, (32, 32, 32), (0, 0))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mjpieters/Development/venvs/stackoverflow-3.6/lib/python3.6/site-packages/PIL/ImageFile.py", line 102, in __init__
    self._open()
  File "/Users/mjpieters/Development/venvs/stackoverflow-3.6/lib/python3.6/site-packages/PIL/TiffImagePlugin.py", line 950, in _open
    self._seek(0)
  File "/Users/mjpieters/Development/venvs/stackoverflow-3.6/lib/python3.6/site-packages/PIL/TiffImagePlugin.py", line 1017, in _seek
    self._setup()
  File "/Users/mjpieters/Development/venvs/stackoverflow-3.6/lib/python3.6/site-packages/PIL/TiffImagePlugin.py", line 1200, in _setup
    raise SyntaxError("unknown pixel mode")
SyntaxError: unknown pixel mode

Solution 2

pyvips can work directly with TIFFs like this. It loads your file as a mono int32 image with two alpha channels.

$ python3
Python 3.8.2 (default, Apr 27 2020, 15:53:34) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyvips
>>> x = pyvips.Image.new_from_file("rgb_CGI.tiff")
>>> x.width, x.height, x.bands, x.format, x.interpretation
(2924, 2088, 3, 'int', 'b-w')
>>> # getpoint reads out a pixel
>>> x.getpoint(10, 10)
[156.0, 141.0, 133.0]
>>> # avg finds the image average
>>> x.avg()
125.31475912560515
>>> 

It ignores the extra GDAL tags, but you can do all the usual 2D image processing, and it's quite a bit quicker than PIL.

Solution 3

I converted the tiff image file from a 64-bit format to a 32-bit format and it worked.

You can do that using ImageMagick 7:

magick oldimage.tiff -depth 8 newimage.tif

or using ImageMagick 6 or earlier:

convert out_0.tiff -depth 8 newimage.tiff
Share:
21,986
ArnJac
Author by

ArnJac

Student Geo Information Sciences and Remote Sensing at the Wageningen University

Updated on July 23, 2020

Comments

  • ArnJac
    ArnJac almost 4 years

    I am trying to open a geotiff file with PIL's Image function. It raises the error:

    OSError: cannot identify image file 'Whatever\\image\\I\\use.tiff'
    

    I saw the question asked here for example, the sollutions are to either use

    Import Image 
    

    instead of

    From PIL import Image
    

    Which is I think an outdated sollution; I can't import Image. An other sollution is to update pillow to 2.9, but 5 years later we are on 5.0.0. I tried 4.0.0 as well where I receive the same error. Is there an up to date sollution for this?

    here is my code and here is a link to a file:

    image_path = 'each\\image\\I\\use.tiff'
    
    from PIL import Image
    Image.open(image_path)
    
    • Martijn Pieters
      Martijn Pieters about 6 years
      No, import Image is not the issue; in the distant past PIL had packaging problems and would not install a proper package (so PIL.Image was installed as Image instead).
    • Martijn Pieters
      Martijn Pieters about 6 years
      If the file can't be opened by PIL / Pillow, then it probably is either not in a supported format, or corrupted. Try with pypi.python.org/pypi/GDAL?
    • Martijn Pieters
      Martijn Pieters about 6 years
      Another possibility is that this file uses compression, which requires that you have libtiff installed, see pillow.readthedocs.io/en/stable/handbook/…. At any rate, without an actual file to test on, we can't help.
    • ArnJac
      ArnJac about 6 years
      I added a file. I can open the file with both gdal and qgis but PIL raises an error. This is just an example though, it behaves the same for every TIFF I use.
    • Martijn Pieters
      Martijn Pieters about 6 years
      Stick with GDAL or convert to a lower bits-per-sample (up to 16) format, I'd say.
    • Martijn Pieters
      Martijn Pieters about 6 years
      If you are interested, this is the debug output: gist.github.com/mjpieters/522f47fa0466d8520ee835bf4006aac4
  • akinuri
    akinuri almost 6 years
    I'm having a similar problem. I've experimented a little, and the problem occurs when trying to open CMYK/16 bit images. It doesn't give error with CMYK/8, RGB/8, or RGB/16. Can you elaborate on how to install and use GDAL? It seems more complicated than Pillow.
  • akinuri
    akinuri almost 6 years
    I've posted a question about GDAL installation because it seems so confusing. I'd appreciate if could you take a look at it: stackoverflow.com/q/50721107/2202732
  • BlaX
    BlaX about 2 years
    FYI pyvips is not a standard module. You need to download Windows binaries and add the bin folder to your path. But it works (where PIL and tifffile failed to load and save my TIF files).