Django PIL : IOError Cannot identify image file

13,750

As ilvar asks in the comments, what kind of object is image? I'm going to assume for the purposes of this answer that it's the file property of a Django ImageField that comes from a file uploaded by a remote user.

After a file upload, the object you get in the ImageField.file property is a TemporaryUploadedFile object that might represent a file on disk or in memory, depending on how large the upload was. This object behaves much like a normal Python file object, so after you have read it once (to make the first thumbnail), you have reached the end of the file, so that when you try to read it again (to make the second thumbnail), there's nothing there, hence the IOError. To make a second thumbnail, you need to seek back to the beginning of the file. So you could add the line

image.seek(0)

to the start of your image_resizer function.

But this is unnecessary! You have this problem because you are asking the Python Imaging Library to re-read the image for each new thumbnail you want to create. This is a waste of time: better to read the image just once and then create all the thumbnails you want.

Share:
13,750
enri
Author by

enri

Updated on June 14, 2022

Comments

  • enri
    enri almost 2 years

    I'm learning Python and Django.

    An image is provided by the user using forms.ImageField(). Then I have to process it in order to create two different sized images.

    When I submit the form, Django returns the following error:

    IOError at /add_event/
    cannot identify image file
    

    I call the resize function:

    def create_event(owner_id, name, image):         
        image_thumb = image_resizer(image, name, '_t', 'events', 180, 120)  
        image_medium = image_resizer(image, name, '_m', 'events', 300, 200)
    

    I get en error when image_resizer is called for the second time:

    def image_resizer(image, name, size, app_name, length, height): 
        im = Image.open(image)
        if im.mode != "RGB":
            im = im.convert("RGB")
        im = create_thumb(im, length, height)
        posit = str(MEDIA_ROOT)+'/'+app_name+'/'
        image_2 = im
        image_name = name + size +'.jpg' 
        imageurl = posit + image_name
        image_2.save(imageurl,'JPEG',quality=80)
        url_image='/'+app_name+'/'+image_name  
        return url_image
    

    Versions:
    Django 1.3.1
    Python 2.7.1
    PIL 1.1.7

    I'm trying to find the problem, but i don't know what to do. Thank you in advanced!

    EDIT
    I solved rewriting the function; now it creates the different images in batch:

    I call the resize function:

    url_array = image_resizer.resize_batch(image, image_name, [[180,120,'_t'], [300,200,'_m']], '/events/')  
    

    so:

    image_thumb = url_array[0]
    image_medium = url_array[1]
    

    and the resize function:

    def resize_batch(image, name, size_array, position):
        im = Image.open(image)
        if im.mode != "RGB":
            im = im.convert("RGB")
        url_array = []
        for size in size_array:
            new_im = create_thumb(im, size[0], size[1])
            posit = str(MEDIA_ROOT) + position
            image_name = name + size[2] +'.jpg' 
            imageurl = posit + image_name
            new_im.save(imageurl,'JPEG',quality=90)
            new_url_array = position + image_name
            url_array.append(new_url_array)
        return url_array
    

    Thanks to all!