2012-09-06 24 views
2

因此,我在Django中有一個用於將圖像上傳到ImageField的窗體。這很好。然後,我將request.FILES ['image']關閉到一個名爲MakeThumbnail的函數,以便進一步處理。從Django ImageField.file製作縮略圖並轉換回圖像

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)。它給了我以下錯誤:預期的讀取緩衝區,找到的實例

我想我可能會失敗回縮略圖= 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

非常感謝你的幫助,揚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 
+0

喜!即時通訊非常新的django,我也想添加一個縮略圖生成一個管理員上傳圖像。我會把這段代碼放在模型上嗎?感謝您的幫助:) –

+0

不應該將'img'傳遞給'StringIO.StringIO(img)'? –

+0

img.save標籤容納了一行代碼爲我們照顧這件事。我不確定是否將PIL Image對象傳遞到StringIO不會。我的猜測是,StringIO尋找一個讀取方法,我假設PIL Image實現了,所以我想這個解決方案也可以。 – Nick

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

從PIL文件約Image.thumbnail

Modifies the image to contain a thumbnail version of itself, no larger than the given size. This method calculates an appropriate thumbnail size to preserve the aspect of the image, calls the draft method to configure the file reader (where applicable), and finally resizes the image.

這意味着您的縮略圖是img,而不是在thumbnail變量,因爲Image.thumbnail不返回任何東西(因此None

另一個錯誤將PIL.Image設置爲StringIO。你最好saveStringIO

所以,你的代碼應該看起來更像是這樣的:

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