I would like to resize and optimize image on save. But only on the first save of image, not on all save. Also I would like to rename file and automatically overwrite old file if new file is uploaded.
Goal is to
- rename images to /menues/{shopid}.jpg (also change from png to jpg)
- optimize image for web
- rescale width and height if image to max 1400 width/height
Below is the code I have created untill now.
def get_upload_path(instance, filename):
name, ext = 'menu', os.path.splitext(filename)[1]
if instance.shopid: # shopid is defined by form view right before create()
return os.path.join("menues", instance.shopid + ext)
return os.path.join('menues', filename)
def scale_dimensions(width, height, longest_side):
if width > height:
if width > longest_side:
ratio = longest_side*1./width
return (int(width*ratio), int(height*ratio))
elif height > longest_side:
ratio = longest_side*1./height
return (int(width*ratio), int(height*ratio))
return (width, height)
from PIL import Image
import os
MAX_MENU_IMG_MB = 10.0
IMG_RESIZE_LONGEST_SIDE = 1400
class Shop(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
shopid = models.CharField(max_length=14, blank=True, editable=False)
name = models.CharField()
menu = models.ImageField(_("Photo (Max %sMB)") % str(MAX_MENU_IMG_MB), upload_to=get_upload_path, null=False, blank=False)
def save(self):
super(Shop, self).save()
if self.menu:
image = Image.open(self.menu.path)
(width, height) = image.size
(new_width, new_height) = scale_dimensions(width, height, longest_side=IMG_RESIZE_LONGEST_SIDE)
if new_width < width or new_height < height:
image = image.resize((new_width, new_height))
image.save("%s.jpg" % self.menu.path.split('.')[0], format='JPEG', quality=70, optimize=True)