Django PIL: IOError Не удается идентифицировать файл изображения - PullRequest
7 голосов
/ 31 марта 2012

Я изучаю Python и Django.

Изображение предоставляется пользователем с помощью forms.ImageField ().Затем мне нужно обработать его, чтобы создать два изображения разных размеров.

Когда я отправляю форму, Django возвращает следующую ошибку:

IOError at /add_event/
cannot identify image file

Я вызываю функцию изменения размера:

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)

Я получаю ошибку при повторном вызове image_resizer:

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

Версии:
Django 1.3.1
Python 2.7.1
PIL 1.1.7

Я пытаюсь найти проблему, но я не знаю, что делать.Спасибо заранее!

РЕДАКТИРОВАТЬ
Я решил переписать функцию;теперь он создает различные изображения в пакете:

Я вызываю функцию изменения размера:

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

так:

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

и функцию изменения размера:

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

Спасибо всем!

Ответы [ 2 ]

19 голосов
/ 31 марта 2012

Как ильвар спрашивает в комментариях , что это за объект image?Для целей этого ответа я предполагаю, что это свойство file Django ImageField, полученное из файла, загруженного удаленным пользователем.

После загрузки файла объект, который выget в свойстве ImageField.file является объектом TemporaryUploadedFile, который может представлять файл на диске или в памяти , в зависимости от размера загрузки.Этот объект ведет себя во многом как обычный объект файла Python , поэтому после того, как вы прочитали его один раз (чтобы сделать первый эскиз), вы достигли конца файла, так что при попытке прочитать его снова(чтобы сделать второй эскиз), там ничего нет, отсюда IOError.Чтобы сделать второй эскиз, вам нужно искать назад к началу файла.Таким образом, вы можете добавить строку

image.seek(0)

в начало вашей функции image_resizer.

Но это не нужно!У вас есть эта проблема, потому что вы просите библиотеку изображений Python перечитать изображение для каждого нового эскиза, который вы хотите создать.Это пустая трата времени: лучше прочитать изображение всего один раз, а затем создать все нужные эскизы.

0 голосов
/ 31 марта 2012

Я предполагаю, что это TemporaryUploadedFile ... найти это с типом (изображение).

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()

Я не уверен на 100% в коде выше ... приходит от 2уроки, которые у меня есть для работы с изображениями ... но попробуйте.

Если это InMemoryUploadedFile, ваш код должен работать!

...