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



所以我在Django中有一个表单,用于将图像上传到ImageField。这很有效。然后我拒绝了这个请求。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

stacktrace表示我在以下行失败:newFile=ContentFile(thumbnailString)。它给了我以下错误:预期的读取缓冲区,实例找到

不过,在查看了局部变量之后,我想我可能会在thumbna=img.thumbna[(128128),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>

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

谢谢!

非常感谢您的帮助,Jan Spurny。我是在你的帮助下想出来的。因此,当img保存到thumbnailString时,需要做一些事情。上面的代码实际上产生了一个错误,因为我们向ContentFile传递了一个实例,而不是缓冲区。不管怎样,我们只需要调用thumbnailString.read()即可。但是thumbnail String.red()返回"。原来我们需要事先做thumbnailString.search(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

来自关于Image.thumbnail:的PIL文档

修改图像以包含其自身的缩略图版本,而不是更大大于给定的大小。此方法计算适当的缩略图size以保留图像的外观,调用draft方法配置文件读取器(如果适用),并最终调整形象

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

另一个错误是将PIL.Image设置为StringIO。你最好把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

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

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):

最新更新