DEV Community

Andrei Koptev
Andrei Koptev

Posted on • Updated on

Django image resize on the fly

Init

Django model with image field

Purpose

Resize image to some template size (typed size)

Short

  • Catch original image from field
  • Resize it through PIL and save to BytesIO output
  • Send output to ContentFile
  • Send ContentFile to File
  • Run self.avatar.save(<name>, file, save=False) in model save method

Detail

ResizeImageMixin

import uuid
from PIL import Image
from io import BytesIO
from django.core.files import File
from django.core.files.base import ContentFile
from django.db import models


class ResizeImageMixin:
    def resize(self, imageField: models.ImageField, size:tuple):
        im = Image.open(imageField)  # Catch original
        source_image = im.convert('RGB')
        source_image.thumbnail(size)  # Resize to size
        output = BytesIO()
        source_image.save(output, format='JPEG') # Save resize image to bytes
        output.seek(0)

        content_file = ContentFile(output.read())  # Read output and create ContentFile in memory
        file = File(content_file)

        random_name = f'{uuid.uuid4()}.jpeg'
        imageField.save(random_name, file, save=False)
Enter fullscreen mode Exit fullscreen mode

models.py

class User(Base, AbstractUser, ResizeImageMixin):
    def __str__(self):
        return f'{self.username}'

    def save(self, *args, **kwargs):
        if self.pk is None:
            self.resize(self.avatar, (200, 200))

        super().save(*args, **kwargs)
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
jandsol profile image
Juan Andrade • Edited

Thanks, this post is very useful!