从Django ImageField.file制作缩略图并转换回图像

Nic*_*ick 3 python django python-imaging-library

所以我在Django中有一个用于将图像上传到ImageField的表单.这很好用.然后我将request.FILES ['image']传递给一个名为MakeThumbnail的函数进行进一步处理.

MakeThumbnail工作得不好.我已经从一系列StackOverflow线程中组装了这个,但我认为我缺少一些关键概念.这是我的代码.

    def MakeThumbnail(file):
        img = Image.open(file)
        thumbnail = img.thumbnail((128, 128), Image.ANTIALIAS)
        thumbnailString = StringIO.StringIO(thumbnail)
        newFile = ContentFile(thumbnailString)
        return newFile
Run Code Online (Sandbox Code Playgroud)

stacktrace说我在这一行上失败了:newFile = ContentFile(thumbnailString).它给我以下错误:预期的读缓冲区,找到实例

不过,在查看局部变量后,我想我可能会在thumbnail = img.thumbnail((128,128),Image.ANTIALIAS)中失败了:

thumbnailString : <StringIO.StringIO instance at 0x0000000003B39748>
file : <InMemoryUploadedFile: Desert.jpg (image/jpeg)>
thumbnail : None
img : <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=128x96 at 0x3B25C08>
Run Code Online (Sandbox Code Playgroud)

请注意,缩略图是none.它应该包含一些东西.有人对我有一些提示吗?

谢谢!

Nic*_*ick 5

非常感谢你的帮助,Jan Spurny.我在你的帮助下想出来了.因此,当img保存到thumbnailString时,需要做一些事情.上面的代码实际上会产生错误,因为我们将实例传递给ContentFile而不是缓冲区.无论如何,我们只需要调用thumbnailString.read().但是thumbnailString.read()返回''.事实证明我们需要事先做thumbnailString.seek(0).但这也不起作用!

最终,我能够使用InMemoryUploadedFile将图像文件恢复为Django文件.

以下是代码从头到尾的样子:

from django.core.files.uploadedfile import InMemoryUploadedFile
import StringIO
def MakeThumbnail(file):
    img = Image.open(file)
    img.thumbnail((128, 128), Image.ANTIALIAS)
    thumbnailString = StringIO.StringIO()
    img.save(thumbnailString, 'JPEG')
    newFile = InMemoryUploadedFile(thumbnailString, None, 'temp.jpg', 'image/jpeg', thumbnailString.len, None)
    return newFile
Run Code Online (Sandbox Code Playgroud)