Django PIL:IOError无法识别图像文件

enr*_*nri 7 python django image python-imaging-library

我正在学习Python和Django.

用户使用forms.ImageField()提供图像.然后我必须处理它以创建两个不同大小的图像.

当我提交表单时,Django返回以下错误:

IOError at /add_event/
cannot identify image file
Run Code Online (Sandbox Code Playgroud)

我调用resize函数:

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)
Run Code Online (Sandbox Code Playgroud)

第二次调用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
Run Code Online (Sandbox Code Playgroud)

版本:
Django 1.3.1
Python 2.7.1
PIL 1.1.7

我试图找到问题,但我不知道该怎么做.先谢谢你!

编辑
我解决了重写功能; 现在它批量创建不同的图像:

我调用resize函数:

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

所以:

image_thumb = url_array[0]
image_medium = url_array[1]
Run Code Online (Sandbox Code Playgroud)

和调整大小功能:

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
Run Code Online (Sandbox Code Playgroud)

谢谢大家!

Gar*_*ees 19

正如ilvar在评论中所说的那样,对象是image什么?为了这个答案的目的,我将假设它是来自远程用户上传的文件file的Django 的属性ImageField.

上传文件后,您在ImageField.file属性中获得的TemporaryUploadedFile对象是一个可能代表磁盘或内存中文件的对象,具体取决于上载的大小.这个对象的行为很像普通的Python文件对象,所以在你读完一次之后(制作第一个缩略图),你已到达文件的末尾,这样当你再次尝试读取它时(制作第二个缩略图) ),那里什么也没有,因此IOError.为了使第二缩略图,你需要寻求回文件的开头.所以你可以添加这条线

image.seek(0)
Run Code Online (Sandbox Code Playgroud)

到你的image_resizer功能的开始.

但这是不必要的!您遇到此问题是因为您要求Python Imaging Library重新读取您要创建的每个新缩略图的图像.这是浪费时间:最好只读取一次图像,然后创建所需的所有缩略图.