Рубрики
Без рубрики

Создание изображения из URL-адреса данных64 с Python Django

Несколько дней назад, в то время как разрабатывая реестр статьи Базара, я впал в несколько сложных сит … Теги с Python, Django, WebDev, учебником.

Несколько дней назад, разрабатывая Базар Регистр статьи, я попал в несколько сложную ситуацию. Возможно, твое похоже.

При создании новой статьи в Базар Выбранные изображения читаются с помощью FialeReader API Чтобы генерировать Dataurl изображений, чтобы сохранить его, позволяя пользователю оставить Bazaar, вернуться назад и продолжайте создавать статью с выбранными изображениями.

Как ссылка на Файл Из каждого изображения теряется, при загрузке изображений необходимо было отправить dataurl вместо самого файла, в этом случае API должен быть ответственным за создание файлов изображений

Примечание. Использование Python 3.6.9 и Django в версии 3.0.3

Для этого были необходимы следующие библиотеки для выполнения этой небольшой задачи.

# python standard lib
import base64, secrets, io

# django and pillow lib
from PIL import Image
from django.core.files.base import ContentFile

Я определил эту функцию, способную принять dataurl для генерации файла и изменять размер при необходимости.

def get_image_from_data_url( data_url, resize=True, base_width=600 ):

    # getting the file format and the necessary dataURl for the file
    _format, _dataurl       = data_url.split(';base64,')
    # file name and extension
    _filename, _extension   = secrets.token_hex(20), _format.split('/')[-1]

    # generating the contents of the file
    file = ContentFile( base64.b64decode(_dataurl), name=f"{_filename}.{_extension}")

    # resizing the image, reducing quality and size
    if resize:

        # opening the file with the pillow
        image = Image.open(file)
        # using BytesIO to rewrite the new content without using the filesystem
        image_io = io.BytesIO()

        # resize
        w_percent    = (base_width/float(image.size[0]))
        h_size       = int((float(image.size[1])*float(w_percent)))
        image        = image.resize((base_width,h_size), Image.ANTIALIAS)

        # save resized image
        image.save(image_io, format=_extension)

        # generating the content of the new image
        file = ContentFile( image_io.getvalue(), name=f"{_filename}.{_extension}" )

    # file and filename
    return file, ( _filename, _extension )

Ну, на данный момент, у нас еще нет сгенерированного файла, Просто содержимое файла (с помощью API Django ContentFile API, который возвращает его экземпляр), сохраненный в памяти и готов к записанию в файл в файловой системе

Однако с Файл Это возвращается, нам нужно только сделать следующее, чтобы генерировать файл и сохранить использование Ошибка хранения файловой системы :

Пример:

# for example
from .models import User
from .utils.images import get_image_from_data_url

def create_user_view(request)

    username = request.POST.get('username')
    # getting the file instance
    avatar_file = get_image_from_data_url(request.POST.get('avatar'))[0]

    # create a user and generate and save the file using the default filesystem storage
    user = User.objects.create(
        username=username,
        avatar=avatar_file
    )

    # this does not work 😂
    return Response(user, status=status.HTTP_201_CREATED)

Конечно, вы будете делать больше валидаций, ведь в вашем случае это не будет простом примером права 😉

Как бонус 😎, я определил вторую функцию, способную генерировать содержание файла для основного изображения и для второго миниатюрное изображение (Копирование изображений, но с гораздо меньшим размером, подходит для Ленивые изображения нагрузки Среди других ситуаций).

def get_image_and_thumbnail_from_data_url( data_url, resize=True, base_width=600):
    #
    file, filename = get_image_from_data_url(data_url, resize, base_width)

    #
    thumbnail = Image.open(file)

    #
    thumbnail_io = io.BytesIO()
    thumbnail.thumbnail((128,128), Image.ANTIALIAS)
    thumbnail.save(thumbnail_io, format=filename[1])

    # thumbnail image
    thumbnail = ContentFile( 
        thumbnail_io.getvalue(), 
        name=f"{filename[0]}.thumbnail.{filename[1]}"
    )

    return file, thumbnail

Итак, вот это сейчас! Я надеюсь, что этот маленький совет может помочь вам. Но будьте осторожны, что в зависимости от ситуации эти операции могут быть очень дорогостоящими. В случае нескольких изображений рекомендуется выполнять операции на заднем плане, используя Сельдерей Например (может быть, я сделаю вторую статью, реализующую Сельдерей , что ты думаешь? 🤔).

Так что пользователь не долго ждал долго, прежде чем получить ответ с сервера.

Обязательно прокомментируйте свой долг, критику или предложение! Наслаждайтесь и следуйте за моим работой в социальных сетях.

Ageu Matheus : @txiocoder

Оригинал: “https://dev.to/txiocoder/creating-image-from-dataurl-base64-with-pyhton-django-454g”