4

所以我在 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

堆栈跟踪说我在这条线上失败了: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>

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

谢谢你!

4

3 回答 3

7

非常感谢您的帮助,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
于 2012-09-06T23:47:46.517 回答
3

从 PIL 文档中关于Image.thumbnail

修改图像以包含其自身的缩略图版本,不大于给定大小。此方法计算适当的缩略图大小以保留图像的方面,调用草稿方法来配置文件阅读器(如果适用),最后调整图像大小。

这意味着您的缩略图在 中img,而不是在thumbnail变量中,因为Image.thumbnail不返回任何内容(因此None

另一个错误是PIL.ImageStringIO. 你最好把save它变成StringIO

所以你的代码应该看起来更像这样:

def MakeThumbnail(file):
    img = Image.open(file)
    img.thumbnail((128, 128), Image.ANTIALIAS)
    thumbnailString = StringIO.StringIO()
    img.save(thumbnailString, 'PNG')
    newFile = ContentFile(thumbnailString)
    return newFile
于 2012-09-06T09:48:59.057 回答
0

我认为您需要将图像的完整路径传递给您的函数,而不是路径的实例。

EX:
models.py
logo = models.ImageField(upload_to=os.path.join(MEDIA_ROOT, "logo"), null=True, default=None)

U need to pass
def MakeThumbnail(logo.path):
于 2012-09-06T04:51:32.363 回答