I'm using the Python Flask framework to build a website. Since I'm storing uploaded images in MongoDB, I built a simple endpoint to serve the images by id:
@app.route('/doc/<docId>')
def getDoc(docId):
userDoc = UserDocument.objects(id=docId).first()
if not userDoc:
return abort(404)
return Response(userDoc.file_.read(), mimetype=userDoc.file_.content_type)
This works perfectly well. But because the images are often very large I now want to be able to also serve up thumbnails of the original images. So using Pillow I want to resize the images, store/cache them in /tmp
and serve them up when needed. So I started off with this:
@app.route('/doc/<docId>')
def getDoc(docId):
userDoc = UserDocument.objects(id=docId).first()
if not userDoc:
return abort(404)
desiredWidthStr = request.args.get('width')
desiredHeightStr = request.args.get('height')
if desiredWidthStr or desiredHeightStr:
print 'THUMBNAIL'
# Load the image in Pillow
im = Image.open(userDoc.file_) # <=== THE PROBLEM!!!
# TODO: resize and save the image in /tmp
print 'NORMAL'
return Response(userDoc.file_.read(), mimetype=userDoc.file_.content_type)
When I now comment out the line with the problem and open the front page (which loads a couple of images) all images load fine and I see this (as expected):
THUMBNAIL
NORMAL
THUMBNAIL
NORMAL
THUMBNAIL
NORMAL
212.xx.xx.xx - - [2015-03-19 16:57:02] "GET /doc/54e74956724b5907786e9918?width=100 HTTP/1.1" 200 139588 0.744827
212.xx.xx.xx - - [2015-03-19 16:57:03] "GET /doc/54e7495c724b5907786e991b?width=100 HTTP/1.1" 200 189494 1.179268
212.xx.xx.xx - - [2015-03-19 16:57:03] "GET /doc/5500c5d1724b595cf71b4d49?width=100 HTTP/1.1" 200 264593 1.416928
but when I run the code as I pasted it above (with the problem line not commented) the images don't load, and I see this in the terminal:
THUMBNAIL
THUMBNAIL
THUMBNAIL
NORMAL
NORMAL
NORMAL
212.xx.xx.xx - - [2015-03-19 16:58:11] "GET /doc/54e74956724b5907786e9918?width=100 HTTP/1.1" 200 138965 0.657734
212.xx.xx.xx - - [2015-03-19 16:58:11] "GET /doc/54e7495c724b5907786e991b?width=100 HTTP/1.1" 200 188871 0.753112
212.xx.xx.xx - - [2015-03-19 16:58:11] "GET /doc/5500c5d1724b595cf71b4d49?width=100 HTTP/1.1" 200 257495 1.024860
Except for these things I see no error whatsoever in the terminal. When I try to load a direct url in the browser it says The image cannot be displayed because it contains errors.
. I now wonder about two things:
Does anybody know why the images are not served when I load them into Pillow? All tips are welcome!
You don't have any problems with Pillow. Your problem is that you are serving an empty response. If you are serving a thumbnail, you ask Pillow to read the file:
if desiredWidthStr or desiredHeightStr:
print 'THUMBNAIL'
im = Image.open(userDoc.file_) # reads from the file object
You then try and serve from that same file object:
if desiredWidthStr or desiredHeightStr:
print 'THUMBNAIL'
# Load the image in Pillow
im = Image.open(userDoc.file_) # <=== THE PROBLEM!!!
# TODO: resize and save the image in /tmp
return Response(userDoc.file_.read(), mimetype=userDoc.file_.content_type)
The userDoc.file_.read()
here will return, at best, a partial image since Image.open()
has already moved the file pointer. It depends on the image type how much is actually read and where the image pointer is located at by that time.
Add in a file.seek()
call and you'll see your image re-appear:
if desiredWidthStr or desiredHeightStr:
print 'THUMBNAIL'
# Load the image in Pillow
im = Image.open(userDoc.file_)
print 'NORMAL'
userDoc.file_.seek(0) # ensure we are reading from the start
return Response(userDoc.file_.read(), mimetype=userDoc.file_.content_type)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With