8
from PIL import Image
from bson import Binary

img = Image.open('test.jpg')
img = Binary(img)

throws an error stating TypeError : data must be an instance of bytes

Why does this happen? And how to resolve this to store the img to MongoDB?

Rahul Dev
  • 602
  • 1
  • 6
  • 16

2 Answers2

10

As long as the document doesn't exceed 16MB standard bson is fine, otherwise gridfs should be used. The example below shows how an image can be inserted and read back from a mongodb.

insert_image.py

from pymongo import MongoClient
from PIL import Image
import io

client = MongoClient()
db = client.testdb
images = db.images

im = Image.open("./image.jpg")

image_bytes = io.BytesIO()
im.save(image_bytes, format='JPEG')

image = {
    'data': image_bytes.getvalue()
}

image_id = images.insert_one(image).inserted_id

read_image.py

from pymongo import MongoClient
from bson.binary import Binary
from PIL import Image
import io
import matplotlib.pyplot as plt

client = MongoClient()
db = client.testdb
images = db.images
image = images.find_one()

pil_img = Image.open(io.BytesIO(image['data']))
plt.imshow(pil_img)
plt.show()
Kirk
  • 141
  • 1
  • 8
3

You need to convert the image into a Byte array. You can do this as follows,

from PIL import Image
from bson import Binary

img = Image.open('test.jpg')

imgByteArr = io.BytesIO()
img.save(imgByteArr, format='PNG')
imgByteArr = imgByteArr.getvalue()

You can try to save imgByteArr into mongo

OR

You can convert image into string and then store it in mongo:

import base64

with open("test.jpg", "rb") as imageFile:
    str = base64.b64encode(imageFile.read())
    //store str in mongo

To get back image

with open("test2.jpg", "wb") as fimage:
    fimage.write(str.decode('base64'))
Anirudh Bagri
  • 2,346
  • 1
  • 21
  • 33