Search code examples
pythonpython-3.xpython-imaging-library

Python PIL error 'L' format requires 0 <= number <= 4294967295


I create a numpy array of int, then I transform it as a PIL Image of type uint32, and then I try to save it. See simple mock code below:

import numpy
resLabels = numpy.ndarray(shape=(38000, 38000), dtype=numpy.int32)
resLabels.fill(0)
resLabels[0,0] = 10000000 # Just a dumb value to ensure that the int32 is required.
arr = resLabels.astype("uint32")
im = Image.fromarray(arr)
im.save("Test.tif")

Unfortunately I get the following error on the last line when trying to save the image:

Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/Users//miniconda3/envs/Py39dev/lib/python3.9/site-packages/PIL/Image.py", line 2431, in save
save_handler(self, fp, filename)
      File "/Users//miniconda3/envs/Py39dev/lib/python3.9/site-packages/PIL/TiffImagePlugin.py", line 1860, in _save
offset = ifd.save(fp)
      File "/Users//miniconda3/envs/Py39dev/lib/python3.9/site-packages/PIL/TiffImagePlugin.py", line 945, in save
result = self.tobytes(offset)
      File "/Users//miniconda3/envs/Py39dev/lib/python3.9/site-packages/PIL/TiffImagePlugin.py", line 889, in tobytes
data = self._write_dispatch[typ](self, *values)
      File "/Users//miniconda3/envs/Py39dev/lib/python3.9/site-packages/PIL/TiffImagePlugin.py", line 699, in <lambda>
b"".join(self._pack(fmt, value) for value in values)
      File "/Users//miniconda3/envs/Py39dev/lib/python3.9/site-packages/PIL/TiffImagePlugin.py", line 699, in <genexpr>
b"".join(self._pack(fmt, value) for value in values)
      File "/Users//miniconda3/envs/Py39dev/lib/python3.9/site-packages/PIL/TiffImagePlugin.py", line 666, in _pack
return struct.pack(self._endian + fmt, *values)
struct.error: 'L' format requires 0 <= number <= 4294967295

After a quick test, it seems to come from the image dimensions. Everything works fine for images 30Kx30K, but fails for images 40Kx40K.

How can this be fixed?


Solution

  • I test the overall size of my image: if width x height x channels x encoding is greater than 4294967295, then I use the tifffile library.