Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django PIL : IOError Cannot identify image file

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!

like image 849
enri Avatar asked Mar 30 '12 21:03

enri


1 Answers

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.

like image 119
Gareth Rees Avatar answered Oct 29 '22 22:10

Gareth Rees