DEV Community

loading...

Django image resize on the fly

Andrei Koptev
Full stack developer
Updated on ・1 min read

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

Discussion (0)