2015-10-05 103 views
4

具有縮略圖像一個Django模型,如:如何將枕頭圖像對象保存到Django ImageField中?

class Thumb(models.Model): 
    thumb = models.ImageField(upload_to='uploads/thumb/', null=True, default=None) 

視圖生成與pillow包的縮略圖,並應保存在一個Thumb例如,使用如下代碼:

image.thumbnail((50, 50)) 
inst.thumb.save('thumb.jpg', ???) 

是什麼image的數據爲inst.thumb.save的正確方法???

我能得到以下工作:

thumb_temp = NamedTemporaryFile() 
image.save(thumb_temp, 'JPEG', quality=80) 
thumb_temp.flush() 
inst.thumb.save('thumb.jpg', File(thumb_temp)) 
thumb_temp.close() # Probably required to ensure temp file delete at close 

但似乎相當笨拙寫一個臨時文件只是內部數據傳遞給inst.thumb.save,所以我不知道是否有一個更優雅的方式做到這一點。 Django class NamedTemporaryFile的文檔。

回答

2

下面是一個工作示例(Python3,django 1.11),它從Model.ImageField獲取圖像,使用PIL(Pillow)對其執行調整大小操作,然後將生成的文件保存到同一個ImageField。希望這應該很容易適應您對模型圖像進行的任何處理。

from io import BytesIO 
from django.core.files.uploadedfile import InMemoryUploadedFile 
from django.core.files.base import ContentFile 

IMAGE_WIDTH = 100 
IMAGE_HEIGHT = 100 

def resize_image(image_field, width=IMAGE_WIDTH, height=IMAGE_HEIGHT, name=None): 
    """ 
    Resizes an image from a Model.ImageField and returns a new image as a ContentFile 
    """ 
    img = Image.open(image_field) 
    if img.size[0] > width or img.size[1] > height: 
     new_img = img.resize((width, height)) 
    buffer = BytesIO() 
    new_img.save(fp=buffer, format='JPEG') 
    return ContentFile(buffer.getvalue()) 

#assuming your Model instance is called `instance` 
image_field = instance.image_field 
img_name = 'my_image.jpg' 
img_path = settings.MEDIA_ROOT + img_name 

pillow_image = resize_image(
        image, 
        width=IMAGE_WIDTH, 
        height=IMAGE_HEIGHT, 
        name=img_path) 

image_field.save(img_name, InMemoryUploadedFile(
    pillow_image,  # file 
    None,    # field_name 
    img_name,   # file name 
    'image/jpeg',  # content_type 
    pillow_image.tell, # size 
    None)    # content_type_extra 
) 
相關問題