How to save pillow image object in Django ImageField?

Having a Django model for a thumbnail:

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

A sketch with the pillow package is created in the view and you should save it in a Thumb instance using the following code:

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

What is the correct way to make image data for inst.thumb.save in ??? ?

I managed to get the work below:

 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 

But it seems quite inconvenient to write a temporary file to transfer internal data to inst.thumb.save , so I wonder if there is a more elegant way to do this. Documentation for the Django NamedTemporaryFile .

+5
source share
1 answer

Here's a working example (Python3, django 1.11) that takes an image from Model.ImageField , performs a resize operation using PIL (Pillow), and then saves the resulting file to the same ImageField. We hope this will easily adapt to any processing that you must do with the images of your models.

 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 ) 
+4
source

Source: https://habr.com/ru/post/1232957/


All Articles