我正在学习Python和Django。
用户使用forms.ImageField()提供图像。然后我必须处理它才能创建两个不同大小的图像。
当我提交表单时,Django会返回以下错误:
IOError at /add_event/
cannot identify image file
我调用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)
第二次调用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
我正试图找到问题,但我不知道该怎么做。先谢谢你了!
修改
我解决了重写功能;现在它批量创建不同的图像:
我调用resize函数:
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
感谢所有人!
答案 0 :(得分:19)
评论中的ilvar asks,image
是什么类型的对象?为了这个答案的目的,我将假设它是来自远程用户上传的文件的Django file
的{{1}}属性。
文件上传后,ImageField
属性中的对象是ImageField.file
对象,可能代表a file on disk or in memory,具体取决于上传的大小。此对象的行为与普通Python file object非常相似,因此在您读取一次之后(制作第一个缩略图),您已到达文件的末尾,以便在您尝试再次读取时(以使其成为第二个缩略图),那里没有任何东西,因此TemporaryUploadedFile
。要制作第二个缩略图,您需要seek返回文件的开头。所以你可以添加一行
IOError
到image.seek(0)
功能的开头。
但这是不必要的!您遇到此问题是因为您要求Python Imaging Library重新读取您要创建的每个新缩略图的图像。这是浪费时间:最好只读取一次图像,然后创建所需的所有缩略图。
答案 1 :(得分:-2)
我猜这是一个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
您的代码应该有效!