ArnJac
ArnJac

Reputation: 362

Image.open gives error Cannot identify image file

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)

Upvotes: 4

Views: 31341

Answers (3)

jcupitt
jcupitt

Reputation: 11220

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.

Upvotes: 1

Hima bindu Bhardwaj
Hima bindu Bhardwaj

Reputation: 11

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

Upvotes: 1

Martijn Pieters
Martijn Pieters

Reputation: 1125078

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

Upvotes: 15

Related Questions