Django PIL: IOError Cannot Detect Image File

I am learning Python and Django.

The image is provided by the user using forms.ImageField (). Then I have to process it to create two images of different sizes.

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 an en error when calling image_resizer a 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 am trying to find a problem, but I do not know what to do. Thank you for your help!

EDIT
I decided to rewrite the function; Now it creates various images in batch mode:

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 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 everyone!

+7
source share
2 answers

How does ilvar ask in the comments what kind of image object it is? I am going to assume for the purpose of this answer that this is a file Django ImageField property that comes from a file downloaded by a remote user.

After downloading the file, the object that you get in the ImageField.file property is a TemporaryUploadedFile object, which can represent the file on disk or in memory , depending on how large the load was. This object behaves like a regular Python file , so after you read it once (to make the first thumbnail), you reach the end of the file, so when you try to read it again (to make the second thumbnail), there’s nothing , therefore IOError . To make a second thumbnail, you need to seek back to the beginning of the file. So you can add a line

 image.seek(0) 

to the top of your image_resizer function.

But it is not necessary! You have this problem because you are asking the Python Imaging Library to re-read the image for each new sketch that you want to create. This is a waste of time: it’s better to read the image only once, and then create all the thumbnails that you want.

+19
source

I assume this is TemporaryUploadedFile ... find this with type (image).

 import cStringIO if isinstance(image, TemporaryUploadedFile): temp_file = open(image.temporary_file_path(), 'rb+') content = cStringIO.StringIO(temp_file.read()) image = Image.open(content) temp_file.close() 

I'm not 100% sure of the above code ... comes from 2 classes that I have for image processing ... but try it.

If there is an InMemoryUploadedFile , your code should work!

-2
source

All Articles