0

I have the following code that creates a thumbnail from a request to a url:

r = requests.get(image_url, stream=True, headers=headers)
size = 500, 500
img = Image.open(r.raw)
thumb = ImageOps.fit(img, size, Image.ANTIALIAS)

At this point I would like to store the image inside a mongo document like so:

photo = {
    'thumbnail': img,
    'source': source,
    'tags': tags,
    'creationDate': datetime.now(),
}

Obviously that won't work so what kind of transformation do I need to apply before I can do this?

davegri
  • 2,206
  • 2
  • 26
  • 45
  • This is a bad idea, never ever ever... ever... store an image in a database... just don't. Store a reference to a url of its location... – Aydin Feb 07 '16 at 10:52
  • It's a ~16KB thumbnail, why not store it in binary? do you actually have a good reason or are you just repeating what you've heard? – davegri Feb 07 '16 at 11:08
  • Im telling you from my first hand experience – Aydin Feb 07 '16 at 11:11
  • You still haven't given me a good reason not to store a 16kb file in binary in a database. mongoose documents can be up to 16MB in size – davegri Feb 07 '16 at 11:31
  • Typing from a phone was a pain, the reason is simple, performance penalties... admittedly 16kb is rather small for an image, but it's still quite large when in comparison to 16kb of text. Whenever you need to serve an image you need to first extract it from the data store, and then proceed to serve it to your user. Since they're thumbnails, you're going to be doing this tens of times on each request, each of those requests add up... Say you gathered the lot in one request, it's still a large transaction for a single (and simple) request. – Aydin Feb 07 '16 at 11:34
  • The final issue is that the plan to serve them in one go... __wont work__ if you store them as an image, because of the way HTTP requests are structured, each image is requested individually... say it took 100ms to serve each image, that's 1s to serve just the images on your page, that isn't even taking into account the time it takes to serve the other content on your site – Aydin Feb 07 '16 at 11:37
  • Thats not true because the binary data is part of the document I'm requesting from mongo so I'm getting the thumbnail and everything else in one request. – davegri Feb 07 '16 at 11:38
  • You could store them in base 64 format, ultimately though it's up to you, I've just given you one form of penalty you face from doing this. – Aydin Feb 07 '16 at 11:38
  • You may be requesting everything in one request from Mongo, but if it's in binary format... you can not serve it back to the client in for example `.jpg` form... so requesting all that data would be a waste of resources because you would have to serve each image individually in that particular case. So the question is in fact whether you have a good reason to be storing images in the data store to begin with – Aydin Feb 07 '16 at 11:56

1 Answers1

2

Okay here are my thoughts on this (I am not certain it will work though; some thoughts adopted from here).

I think you can achieve what you need using the Binary BSON type in pymongo library. Try loading the image in binary. Say using PILLOW (pil.image) or

image_file = open('1.bmp', 'rb')

or as

image_file = StringIO(open("test.jpg",'rb').read())

and then send it to Binary(image_file) type in pymongo

Binary_image_file = Binary(image_file) #pymongo libary

Then do a normal insert in mongo.

To read. do a normal find(). Then load the value from key and convert the data stored to image as:

image_data = StringIO.StringIO(Stringio_image_file)
image = Image.open(image_data)

I hope that helps a little. (also you could go with Aydin base64 proposition).

All the best.

Community
  • 1
  • 1
ibininja
  • 1,209
  • 1
  • 15
  • 29