Evgenii Legotckoi
Evgenii Legotckoi9 февраля 2022 г. 6:11

Django - Урок 056. Как конвертировать изображение в формат WEBP при сохранении в ImageField

Содержание

WEBP - это формат сжатия изображений, который был предложен Google в 2010 году. Главным его преимуществом является низкий размер без видимых потерь качества по сравнению с такими форматами, как JPEG или PNG. Поэтому вполне логично использовать данный формат для хранения изображений на сайте, особенно если у вас нет необходимости хранить оригиналы изображений на сайте.

После длительных поисков я так и не нашёл готового и простого решения, которое бы поддерживало конвертацию изображений в формат WEBP на лету.
Поэтому решил написать свой вариант, который в итоге состоит из пары десяток строчек и прост как деревянная доска.


Реализация

Вся реализация состоит из двух частей:

  • WEBPFieldFile - класс наследник от ImageFieldFile, который производит сохранение файла с автоматической конвертацией в WEBP формат.
  • WEBPField - класс наследний от ImageField, который использует WEBPFieldFile вместо ImageFieldFile

И всё это располагается в одном файле fields.py.

Для работы с изображениями понадобится библиотека Pillow. Поэтому установим её. Впрочем даже просто для использования полей ImageField вам будет нужна эта библиотека.

pip install Pillow

fields.py

Создайте в своём приложении файлы fields.py и добавьте в него следующий код

# -*- coding: utf-8 -*-

import io

from PIL import Image
from django.core.files.base import ContentFile
from django.db import models
from django.db.models.fields.files import ImageFieldFile


class WEBPFieldFile(ImageFieldFile):

    def save(self, name, content, save=True):
        content.file.seek(0)
        image = Image.open(content.file)
        image_bytes = io.BytesIO()
        image.save(fp=image_bytes, format="WEBP")
        image_content_file = ContentFile(content=image_bytes.getvalue())
        super().save(name, image_content_file, save)


class WEBPField(models.ImageField):
    attr_class = WEBPFieldFile

Как видите, в данном коде в классе WEBPFieldFile переопределён метод save() который получает в качестве входного аргумента имя и содержимое файла для сохранения, конвертирует содержимое файла в формат WEBP и после чего методом базового класса сохраняет файл на диск. А класс WEBPField точно такой же как и ImageField с той лишь разницей, что использует модифицированный фариант класса для обработки изображения.

models.py

А теперь давайте воспользуемся новым полем изображения в нашей модели для фотографии.

# -*- coding: utf-8 -*-

import os
import uuid

from django.conf import settings
from django.db import models
from django.utils.translation import gettext_lazy as _

from photo.fields import WEBPField


def image_folder(instance, filename):
    return 'photos/{}.webp'.format(uuid.uuid4().hex)


class Photo(models.Model):
    user = models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    height = models.IntegerField(verbose_name=_('Height'), default=0, blank=True, null=True)
    width = models.IntegerField(verbose_name=_('Width'), default=0, blank=True, null=True)
    image = WEBPField(
        verbose_name=_('Image'),
        upload_to=image_folder,
        height_field='height',
        width_field='width'
    )

Как видите, использование данного поля WEBPField ничем не отличается от использования стандартного поля ImageField .

А в качестве бонуса в данном коде в функции image_folder я добавил генерирование случайного уникального имени файла с помощью uuid .

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Вам это нравится? Поделитесь в социальных сетях!

Владислав Меленчук
  • 19 февраля 2022 г. 1:30

Очень годно!

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
m
  • molni99
  • 26 октября 2024 г. 1:37

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:80баллов,
  • Очки рейтинга4
m
  • molni99
  • 26 октября 2024 г. 1:29

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:20баллов,
  • Очки рейтинга-10

C++ - Тест 003. Условия и циклы

  • Результат:42баллов,
  • Очки рейтинга-8
Последние комментарии
i
innorwall8 ноября 2024 г. 7:40
Qt/C++ - Урок 039. Как закрасить строку в QSqlTableModel по значению в столбце priligy results This slowing of eGFR decline was observed in patients with and without low eGFR and in those with and without type 2 diabetes
i
innorwall8 ноября 2024 г. 2:45
QML - Урок 002. Custom Button in QML Android 2007; 14 2 270 83 priligy dapoxetine 60mg Testicular imaging is sort of a unique niche right now, Гў
i
innorwall8 ноября 2024 г. 1:32
C++ - Ускоряет ли сборку #pragma once? It could cause harm to the unborn baby buy generic priligy
i
innorwall8 ноября 2024 г. 0:50
EVILEG-CORE. Использование Google reCAPTCHA buy priligy 60 urea in 50 patients treated by urea for mild hyponatremia developed it in the intensive care unit mean age 71 20 years
Сейчас обсуждают на форуме
i
innorwall8 ноября 2024 г. 7:08
добавить qlineseries в функции School of Nursing, Long Island University, Brooklyn Campus, Brooklyn, NY, USA priligy dapoxetine 30mg
9
9Anonim25 октября 2024 г. 9:10
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…
ИМ
Игорь Максимов3 октября 2024 г. 4:05
Реализация навигации по разделам Спасибо Евгений!
F
Fynjy22 июля 2024 г. 4:15
при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …

Следите за нами в социальных сетях