Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get content of Django ImageField before it is saved?

I'm trying to resize an image while saving an instance of my model.

class Picture(models.Model):
  image_file = models.ImageField(upload_to="pictures")
  thumb_file = models.ImageField(upload_to="pictures", editable=False)
  def save(self, force_insert=False, force_update=False):
    image_object = Image.open(self.image_file.path)
    #[...] nothing yet
    super(Picture, self).save(force_insert, force_update)

The problem is that self.image_file.path does not exist before the model is being saved. It returns a correct path, but the image is not there yet. Since there is no image, I can't open it in PIL for resize.

I want to store the thumbnail in thumb_file (another ImageField), so I need do the processing before saving the model.

Is there a good way to open the file (maybe get the tmp image object in memory) or do I have to save the whole model first, resize and then save again ?

like image 812
JasonTS Avatar asked Nov 13 '22 12:11

JasonTS


1 Answers

I used this snippet:

import Image

def fit(file_path, max_width=None, max_height=None, save_as=None):
    # Open file
    img = Image.open(file_path)

    # Store original image width and height
    w, h = img.size

    # Replace width and height by the maximum values
    w = int(max_width or w)
    h = int(max_height or h)

    # Proportinally resize
    img.thumbnail((w, h), Image.ANTIALIAS)

    # Save in (optional) 'save_as' or in the original path
    img.save(save_as or file_path)

    return True

And in models:

def save(self, *args, **kwargs):
    super(Picture, self).save(*args, **kwargs)
    if self.image:
        fit(self.image_file.path, settings.MAX_WIDTH, settings.MAX_HEIGHT)
like image 59
Denis Kabalkin Avatar answered Dec 22 '22 10:12

Denis Kabalkin