Несколько дней назад, разрабатывая Базар Регистр статьи, я попал в несколько сложную ситуацию. Возможно, твое похоже.
При создании новой статьи в Базар Выбранные изображения читаются с помощью 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”