Skip to content

Saving TIFF in chunks #4669

@DexterHill0

Description

@DexterHill0

What did you do?

I need to save to save huge image files (approx. 819200x460800 RGBA). This is too much for anyone's RAM so I have to save it in chunks from disk. I start by saving the array to an HDF5 file. I then loop over the array in large steps, and parse a slice of the array into .fromarray(). I then save this to a tiff file. Once it loops again, it will add more to the tiff file and so on.

What did you expect to happen?

It should create an tiff image that is very large.

What actually happened?

It errored out while saving, giving me the error:

ile "c:\Users\Dexter\Desktop\workspace\test.py", line 68, in test
    a.save("ff.tiff", format="tiff", quality=1)
  File "C:\Users\Dexter\AppData\Local\Programs\Python\Python38\lib\site-packages\PIL\Image.py", line 2134, in save
    save_handler(self, fp, filename)
  File "C:\Users\Dexter\AppData\Local\Programs\Python\Python38\lib\site-packages\PIL\TiffImagePlugin.py", line 1629, in _save
    offset = ifd.save(fp)
  File "C:\Users\Dexter\AppData\Local\Programs\Python\Python38\lib\site-packages\PIL\TiffImagePlugin.py", line 865, in save
    result = self.tobytes(offset)
  File "C:\Users\Dexter\AppData\Local\Programs\Python\Python38\lib\site-packages\PIL\TiffImagePlugin.py", line 808, in tobytes
    data = self._write_dispatch[typ](self, *values)
  File "C:\Users\Dexter\AppData\Local\Programs\Python\Python38\lib\site-packages\PIL\TiffImagePlugin.py", line 644, in <lambda>
    b"".join(self._pack(fmt, value) for value in values)
  File "C:\Users\Dexter\AppData\Local\Programs\Python\Python38\lib\site-packages\PIL\TiffImagePlugin.py", line 644, in <genexpr>
    b"".join(self._pack(fmt, value) for value in values)
  File "C:\Users\Dexter\AppData\Local\Programs\Python\Python38\lib\site-packages\PIL\TiffImagePlugin.py", line 611, in _pack
    return struct.pack(self._endian + fmt, *values)
struct.error: argument out of range

What are your OS, Python and Pillow versions?

  • OS: Windows 10 V. 1909
  • Python: 3.8.1
  • Pillow: Latest (7.1.2)
def test():
    f = h5py.File("test.hdf5", "w")
    dset = f.create_dataset("test", (100000,100000,4), dtype=np.uint8, compression='gzip')

    shp = dset.shape
    step = 25000

    for i in range(step, shp[0]+step, step):
        a = Image.fromarray(dset[:i])
        a.save("out.tiff", format="tiff", quality=80) #should error out here
        del a
        gc.collect()

    f.close()
test()

I mention the size 819200x460800 - that's the maximum possible size. I also get the error on the size shown above.
If the size of the image is lower (for instance, 10000x10000) with a step size of 1000, it will not error and will produce an output image in about 4 seconds.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions