Python 如何从发布的base64编码图像创建MongoDB/mongoengine ImageField?
我有一个小型Python/Flask应用程序,它应该在MongoDB中存储图片Python 如何从发布的base64编码图像创建MongoDB/mongoengine ImageField?,python,mongodb,python-imaging-library,mongoengine,imagefield,Python,Mongodb,Python Imaging Library,Mongoengine,Imagefield,我有一个小型Python/Flask应用程序,它应该在MongoDB中存储图片 客户端提交一个HTTP POST(JSON),其中一个字段是base64编码的图像 服务器应将此映像存储在MongoDB ImageField中。我现在正在使用mongoengine 模型: class Image(db.EmbeddedDocument): data = db.ImageField() 现在,相关的服务器代码如下所示: import Image as PIL import base64 i
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)(image.grid:['images'])
当我将图像数据的指定更改为:
img.data.put(PILImage)
我得到错误:#=>验证错误:无效图像:读取
所以我认为它可能正在寻找一个支持“read”方法的对象。当我将作业更改为以下内容时:
img.data.put(file_like)
我收到错误:#=>“验证错误:无效图像:无法识别图像文件”
因此,我能够对数据进行base64编码、json.loads()、POST、json.dumps()、base64解码并创建一个PIL图像,但我无法让MongoDB ImageField将其作为图像接受
有人能帮忙吗
有一件事:我发现,如果我简单地将PILImage写入磁盘,然后通过告诉mongoengine
img.data.put("path/to/image/file")
我可以解决这个问题,但我希望避免文件系统操作,因为应用程序将遇到相当多的流量,我们怀疑IO将是第一个瓶颈。如果您仍然需要它,这里是我的解决方案:
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()
希望它有帮助这会在文件系统上创建一个实际的(临时)文件,对吗?我希望避免这种情况,因为几乎同时发生的数百个事务的I/O成本。是的,这会在文件系统上创建一个实际的临时文件。但根据Mongo doc的说法,这是将img保存到和ImageField的唯一方法。temp文件的一个好处是,一旦您退出了语句(通过正常的exit、return、exception或其他方式),文件/目录及其内容将从文件系统中删除。如果要避免I/O开销,可以尝试将映像保存在StringField中的base64中。希望能有所帮助,抱歉这么晚才回复。谢谢回复。我想这基本上意味着,如果不在I/O方面付出一些小的代价,这是不可能的。您的答案是最接近的(tempfile或stringfield)。谢谢做了这件事,很有魅力。现在尝试查询存储的图像。因此,如果有人知道: