所以我在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
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>
请注意,缩略图是无。它应该包含一些东西。有人对我有一些提示吗?
谢谢你!答案 0 :(得分: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
答案 1 :(得分:3)
关于Image.thumbnail
的PIL文档:
修改图像以包含其自身的缩略图版本,不大 超过给定的大小。此方法计算适当的缩略图 保持图像方面的大小,调用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
答案 2 :(得分:0)
我认为你需要将图像的完整路径传递给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):