Делюсь опытом в описанных технологиях. Блог в первую очередь выполняет роль памяток для меня самого.

Django - изменить размер изображения перед сохранением

2 комментария

Как изменить размер изображения перед сохранением? Никак. Но далее я опишу путь, на который указал пользователь StackOwerflow в своём ответе вот на этот вопрос.

Вкратце:

  • Сохраняем объект
  • Проверяем наличие данных в нужном поле типа ImageField
  • Открываем сохранённое изображение и меняем его свойства, как нам нужно

Пример

from PIL import Image
from django import models

from os import path

# Максимальный размер изображения по большей стороне
_MAX_SIZE = 300

class CarManufacter(models.Model):
    """Производитель автомобилей, два поля
       name - название, строка
       logo - логотип, изображение
    """
    name = models.CharField(
        'Наименование',
        max_length=100,
        unique=True
    )
    logo = models.ImageField(
        upload_to=path.join('car', 'manufacter', 'logo'),
        null=True,
        blank=True
    )

    def save(self, *args, **kwargs):
        # Сначала - обычное сохранение
        super(CarManufacter, self).save(*args, **kwargs)

        # Проверяем, указан ли логотип
        if self.logo:
            filepath = self.logo.path
            width = self.logo.width
            height = self.logo.height

            max_size = max(width, height)

            # Может, и не надо ничего менять?
            if max_size > _MAX_SIZE:
                # Надо, Федя, надо
                image = Image.open(filename)
                # resize - безопасная функция, она создаёт новый объект, а не
                # вносит изменения в исходный, поэтому так
                image = image.resize(
                    (round(width / max_size * _MAX_SIZE),  # Сохраняем пропорции
                    round(height / max_size * _MAX_SIZE)),
                    Image.ANTIALIAS
                )
                # И не забыть сохраниться
                image.save(filename)

2 комментария :

  1. Я пошел другим путем: изменяю размер изображения на стороне браузера, потом отресайзеное лью джанге. А уже джанго сохраняет в модель подготавливает превью.

    ОтветитьУдалить
  2. недавно победил этот момент:

    метод save модели
    def save(self, *args, **kwargs):
    if self.photo and self.photo.file:
    self.photo.file = ImageProcess.ImageProcess(self.photo).get_image()

    ресайзилка:
    import io
    from PIL import Image

    ImageProcess:
    def __init__(self, photo):
    self.__photo = photo
    self.__photo_ratio = photo.height / photo.width

    def __resize_image(self):
    tmp_file = io.BytesIO(self.__photo.read())
    image = Image.open(tmp_file).resize((int(1500/self.__photo_ratio), 1500), Image.ANTIALIAS)
    new_image = io.BytesIO()
    image.save(new_image, 'JPEG', quality=80)
    return new_image

    def get_image(self):
    return self.__resize_image()

    ОтветитьУдалить