DEV Community

Andrei Koptev
Andrei Koptev

Posted on Edited 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!