django优化,重命名,调整图像大小首先保存

时间:2018-04-16 08:53:19

标签: python django django-models imagefield

我想在保存时调整大小并优化图像。但只有第一次保存图像,而不是全部保存。此外,我想重命名文件,并在上传新文件时自动覆盖旧文件。

目标是

  • 将图像重命名为/menues/{shopid}.jpg(也从png更改为jpg)
  • 优化网络图片
  • 如果图像最大1400宽度/高度
  • ,则重新缩放宽度和高度

以下是我现在创建的代码。

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)

1 个答案:

答案 0 :(得分:0)

使用init查看图像更改

def __init__(self):
    super(Shop, self).__init__(*args, **kwargs)
    self.__previous_menu = self.menu if self.id else None

保存时,删除上一张图像和新图像的原始版本

def save(self, *args, **kwargs):
    super().save(*args, **kwargs)
    previous_menu = self.__previous_menu
    if self.menu != previous_menu:
        # delete old image if changed
        if previous_menu:
            os.remove('{}/{}'.format(
                settings.MEDIA_ROOT,previous_menu.name).replace("\\","/"))

        org_file = self.menu
        # resize logic here

        self.__previous_menu = self.menu # to avoid infinite loop
        # remove original version of new image
        os.remove('{}/{}'.format(
            settings.MEDIA_ROOT,org_file.name).replace("\\","/"))
        self.save()