4
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
  • 509
  • 4
  • 14

2 Answers2

6

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
  • 86
  • 1
  • 7
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,097
  • 1
  • 18
  • 28