Как создать поле MongoDB/mongoengine ImageField из опубликованного изображения в кодировке base64?
У меня есть небольшое приложение Python / Flask, которое должно хранить картинку в MongoDB.
- клиент отправляет сообщение HTTP (JSON) с одним из полей, являющимся изображением в кодировке base64.
- сервер должен хранить это изображение в поле MongoDB ImageField. Сейчас я использую монгоинжайн.
Модель:
class Image(db.EmbeddedDocument):
data = db.ImageField()
Прямо сейчас соответствующий код сервера выглядит следующим образом:
import Image as PIL
import base64
import cStringIO # I'm trying to give PIL something that can handle common file operations without having to write to disk
imageData = jsondata['image']
file_like = cStringIO.StringIO(base64.decodestring(imageData))
PILImage = PIL.open(file_like)
# new mongo object
img = Image(name="imagename")
img.data = PILImage # assignment of image data
img.save()
Это дает мне ошибку #=>ValidationError: ValidationError (Местоположение: 53e37ed6844de403e0998182) (изображение.grid_id: ['images'])
Когда я изменяю назначение данных изображения на это:
img.data.put(PILImage)
Я получаю ошибку: # = > ValidationError: недопустимое изображение: read
Поэтому я подумал, что он, возможно, ищет объект, который поддерживает метод "read". Когда я изменяю назначение на это:img.data.put(file_like)
Я получаю ошибку: # = > "ValidationError: недопустимое изображение: не удается идентифицировать файл изображения"
Итак, я могу кодировать base64, json.нагрузки(), пост, формат JSON.dumps (), base64decode и создать PIL-образ из данных, но я почему-то не могу заставить поле MongoDB ImageField принять его в качестве образа.
Может ли кто-нибудь помочь?Одна вещь: я обнаружил, что если я просто запишу Пилимаж на диск, а затем сохраню его, сказав mongoengine
img.data.put("path/to/image/file")
Я могу обойти это, но я хотел бы избежать операций с файловой системой, так как приложение будет испытывать значительное количество трафика, и мы подозреваем, что IO будет первым узким местом.
1 ответ:
Если вам это все еще нужно, вот мое решение:
import tempfile # this can change depending if you send the JSON by url or not file_like = base64.b64decode(imageData) bytes_image = bytearray(file_like) with tempfile.TemporaryFile() as f: f.write(bytes_image) f.flush() f.seek(0) img.data.put(f) img.save()
Надеюсь, это поможет