使用PIL在django中调整上传文件大小

3
我正在使用PIL来调整上传文件的大小,使用以下方法:

def resize_uploaded_image(buf):
  imagefile = StringIO.StringIO(buf.read())
  imageImage = Image.open(imagefile)

  (width, height) = imageImage.size
  (width, height) = scale_dimensions(width, height, longest_side=240)

  resizedImage = imageImage.resize((width, height))
return resizedImage

然后我在主视图方法中使用这种方法来获取调整大小的图像:

image = request.FILES['avatar']
resizedImage = resize_uploaded_image(image)
content = django.core.files.File(resizedImage)
acc = Account.objects.get(account=request.user)
acc.avatar.save(image.name, content)

然而,这给我带来了“read”错误。
跟踪:
异常类型:AttributeError at /myapp/editAvatar 异常值: read
有任何想法如何解决?我已经付出了几个小时的努力! 谢谢!
Nikunj

一个PIL图像对象不是文件。你需要先将其save()到一个StringIO对象中,使用某种编码(例如PNG)。别忘了在将文件写入StringIO后要执行seek(0)!顺便说一句:为什么不直接从buf中读取,避免额外的包装StringIO呢? - Cameron
Cameron,感谢你的回复。我真的很新手,也不太明白正在发生什么。我试图拼凑片段来让它工作。如何保存到StringIO对象?在最上面的方法中使用resizedImage.save().seek(0)就足够了吗?如果你能给我展示一小段代码或一个记录这个的地方,那就太好了 :) 谢谢。 - nknj
由于您似乎关心调整头像的大小,这是非常普遍和标准的事情:不要直接使用PIL调整图像的大小,而是使用专用应用程序(如也使用PIL的easy_thumbnails)可能会更容易:http://easy-thumbnails.readthedocs.org/en/latest/usage/#python - arie
2个回答

4

以下是如何将文件对象转换为PIL图像,然后再将其转回文件对象的方法:

def resize_uploaded_image(buf):
    image = Image.open(buf)

    (width, height) = image.size
    (width, height) = scale_dimensions(width, height, longest_side=240)

    resizedImage = image.resize((width, height))

    # Turn back into file-like object
    resizedImageFile = StringIO.StringIO()
    resizedImage.save(resizedImageFile , 'PNG', optimize = True)
    resizedImageFile.seek(0)    # So that the next read starts at the beginning

    return resizedImageFile

请注意,PIL图像已经有一个方便的thumbnail()方法。这是我在自己项目中使用的缩略图代码的变体:
def resize_uploaded_image(buf):
    from cStringIO import StringIO
    import Image

    image = Image.open(buf)

    maxSize = (240, 240)
    resizedImage = image.thumbnail(maxSize, Image.ANTIALIAS)

    # Turn back into file-like object
    resizedImageFile = StringIO()
    resizedImage.save(resizedImageFile , 'PNG', optimize = True)
    resizedImageFile.seek(0)    # So that the next read starts at the beginning

    return resizedImageFile

1
最好的做法是先保存上传的图像,然后在模板中按照您的意愿显示和调整大小。这样,您就可以在运行时调整图像大小。sorl-thumbnail 是一个 Django 应用程序,您可以用它来调整模板图像大小,它易于使用,您也可以在视图中使用它。这里有关于该应用程序的示例

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接