Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why am I getting "I/O operation on closed file" with PILLOW 3.1.0?

I am attempting to convert a tiff file into a PDF using Pillow and PyPDF. I was able to get this to work using an earlier version of Pillow, although I cannot which version.

I recently upgraded to Pillow 3.1.0, and now I ran into issues. This is the previously working code.

import os
import traceback

from PIL import Image
from PyPDF2 import PdfFileReader, PdfFileMerger

to_merge = []

with Image.open('my_tif.tif') as img:
    seeker = 0

    while True:
        try: 
            # temp file name for PDF
            img_pdf = 'temp_{}.pdf'.format(seeker)

            #seeks to next image with TIFF
            img.seek(seeker)

            # saves the image as a PDF
            img.save(img_pdf)

            seeker += 1
            to_merge.append(img_pdf)

        except Exception as err:
            traceback.print_exc()
            break                

merger = PdfFileMerger()
for f in to_merge:
    merger.append(PdfFileReader(f))
    os.remove(f)
merger.write('merged.pdf')

Beforehand, it generated a PDF for each image within the tiff and then merged the PDFs together with no problem.

After I upgraded to Pillow 3.1.0 it loops through all of the images, but then throws a ValueError on the final image.

Traceback (most recent call last):
  File "C:/Code/Python/tiff_to_pdf.py", line 16, in <module>
    img.save(img_pdf)
  File "C:\Python27\lib\site-packages\PIL\Image.py", line 1675, in save
    save_handler(self, fp, filename)
  File "C:\Python27\lib\site-packages\PIL\PdfImagePlugin.py", line 155, in _save
    im.seek(pageNumber)
  File "C:\Python27\lib\site-packages\PIL\TiffImagePlugin.py", line 930, in seek
    self._seek(max(frame, 0))  # Questionable backwards compatibility.
  File "C:\Python27\lib\site-packages\PIL\TiffImagePlugin.py", line 956, in _seek
    self.fp.seek(self._frame_pos[frame])
ValueError: I/O operation on closed file

What would be the cause of the ValueError?

like image 407
Wondercricket Avatar asked Oct 29 '25 08:10

Wondercricket


1 Answers

Problem

There can be two problems.

  • Image.Image.seek()
    If the image is a single-frame image, the file will be closed in this method after the frame is read. If the image is a multi-frame image, (e.g. multipage TIFF and animated GIF) the image file is left open so that Image.Image.seek() can load the appropriate frame.

  • Image.Image.close()
    Closes the file and destroys the core image object. The Pillow context manager will also close the file, but will not destroy the core image object.

Solution

  1. If you are using Image.Image.seek() function to read the image and want to re-use the image again without opening it.

    What you can do, is copy the loaded image into another variable and perform operation.

    loaded_image = Image.open("test.jpg")
    temp = loaded_image.copy()
    

    Now you can use temp.sheek() to read the image and your loaded image will be safe

  2. If you are not using Image.Image.seek() and facing the same issue then
    you are using Image.Image.close() function that is destroying the image.

    So, do not use Image.Image.close() if you want to re use the image.

Solution Source

File Handling in Pillow Read the Image Lifecycle section

like image 122
Harvindar Singh Avatar answered Oct 30 '25 23:10

Harvindar Singh



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!