Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A flask server for serving all JPEG images in a local directory and subdirectories. Uses unveil.js for lazy-loading of images. Thumbnails are created on the fly by PIL.
#!/bin/python
import os
from flask import Flask, Response, request, abort, render_template_string, send_from_directory
import Image
import StringIO
app = Flask(__name__)
WIDTH = 1000
HEIGHT = 800
TEMPLATE = '''
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<style>
body {
margin: 0;
background-color: #333;
}
.image {
display: block;
margin: 2em auto;
background-color: #444;
box-shadow: 0 0 10px rgba(0,0,0,0.3);
}
img {
display: block;
}
</style>
<script src="https://code.jquery.com/jquery-1.10.2.min.js" charset="utf-8"></script>
<script src="http://luis-almeida.github.io/unveil/jquery.unveil.min.js" charset="utf-8"></script>
<script>
$(document).ready(function() {
$('img').unveil(1000);
});
</script>
</head>
<body>
{% for image in images %}
<a class="image" href="{{ image.src }}" style="width: {{ image.width }}px; height: {{ image.height }}px">
<img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-src="{{ image.src }}?w={{ image.width }}&amp;h={{ image.height }}" width="{{ image.width }}" height="{{ image.height }}" />
</a>
{% endfor %}
</body>
'''
@app.route('/<path:filename>')
def image(filename):
try:
w = int(request.args['w'])
h = int(request.args['h'])
except (KeyError, ValueError):
return send_from_directory('.', filename)
try:
im = Image.open(filename)
im.thumbnail((w, h), Image.ANTIALIAS)
io = StringIO.StringIO()
im.save(io, format='JPEG')
return Response(io.getvalue(), mimetype='image/jpeg')
except IOError:
abort(404)
return send_from_directory('.', filename)
@app.route('/')
def index():
images = []
for root, dirs, files in os.walk('.'):
for filename in [os.path.join(root, name) for name in files]:
if not filename.endswith('.jpg'):
continue
im = Image.open(filename)
w, h = im.size
aspect = 1.0*w/h
if aspect > 1.0*WIDTH/HEIGHT:
width = min(w, WIDTH)
height = width/aspect
else:
height = min(h, HEIGHT)
width = height*aspect
images.append({
'width': int(width),
'height': int(height),
'src': filename
})
return render_template_string(TEMPLATE, **{
'images': images
})
if __name__ == '__main__':
app.run(debug=True, host='::')
@Marventex

This comment has been minimized.

Copy link

Marventex commented Oct 21, 2017

How can i put images? how can i make this server running on the app.. its been hours and still i dont have the solution.. please someone help me..

@musakhan666

This comment has been minimized.

Copy link

musakhan666 commented Oct 22, 2017

same here i also got stuck in that part of creating server

@Marventex

This comment has been minimized.

Copy link

Marventex commented Oct 24, 2017

Does yours crashes too when tapping on the add to cart button or going to the shopping cart screen?

@Marventex

This comment has been minimized.

Copy link

Marventex commented Oct 24, 2017

"The images should be named with the corresponding product ID, and jpg format is preferred. "
i really dont have any idea how to implement this..

@musakhan666

This comment has been minimized.

Copy link

musakhan666 commented Oct 25, 2017

same here it does crash

@Marventex

This comment has been minimized.

Copy link

Marventex commented Oct 25, 2017

do you think the images have something to do with it? the crashing ?
do you think if we can put images the app wont crash anymore?

@Marventex

This comment has been minimized.

Copy link

Marventex commented Oct 25, 2017

do you have any facebook account or email? so we can have a decent talk.

@kingsofcoms

This comment has been minimized.

Copy link

kingsofcoms commented Dec 2, 2017

import os
from flask import Flask, Response, request, abort, render_template_string, send_from_directory
from PIL import Image
import StringIO

app = Flask(__name__)

WIDTH = 640
HEIGHT = 360

TEMPLATE = '''
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<style>
body {
margin: 0;
background-color: #333;
}
.image {
display: inline-block;
margin: 3em 14px;
background-color: #444;
box-shadow: 0 0 10px rgba(0,0,0,0.3);
}
img {
display: block;
}
</style>
<script src="https://code.jquery.com/jquery-1.10.2.min.js" charset="utf-8"></script>
<script src="http://luis-almeida.github.io/unveil/jquery.unveil.min.js" charset="utf-8"></script>
<script>

$(document).ready(function() {
$('img').unveil(1000);
});
</script>
</head>
<body>
{% for image in images %}
    <a class="image" href="{{ image.src }}" style="width: {{ image.width }}px; height: {{ image.height }}px">
        <img src="{{ image.src }}" data-src="{{ image.src }}?w={{ image.width }}&amp;h={{ image.height }}" width="{{ image.width }}" height="{{ image.height }}" />
    </a>
{% endfor %}
</body>
'''

@app.route('/<path:filename>')
def image(filename):
try:
    w = int(request.args['w'])
    h = int(request.args['h'])
except (KeyError, ValueError):
    return send_from_directory('.', filename)

try:
    im = Image.open(filename)
    im.thumbnail((w, h), Image.ANTIALIAS)
    io = StringIO.StringIO()
    im.save(io, format='JPEG')
    return Response(io.getvalue(), mimetype='image/jpeg')

except IOError:
    abort(404)

return send_from_directory('.', filename)

@app.route('/')
def index():
images = []
for root, dirs, files in os.walk('.'):
    files.sort()
    for filename in [os.path.join(root, name) for name in files]:
        if not filename.endswith('.png'):
            continue
        im = Image.open(filename)
        w, h = im.size
        aspect = 1.0*w/h
        if aspect > 1.0*WIDTH/HEIGHT:
            width = min(w, WIDTH)
            height = width/aspect
        else:
            height = min(h, HEIGHT)
            width = height*aspect
        images.append({
            'width': int(width),
            'height': int(height),
            'src': filename
        })

return render_template_string(TEMPLATE, **{
    'images': images
})

if __name__ == '__main__':
app.run(host="127.0.0.1", port="3000")

install flask, pillow
Save as app.py
Run

python app.py
@mustafa-qamaruddin

This comment has been minimized.

Copy link

mustafa-qamaruddin commented May 9, 2018

Very helpful, thank you
I only had to change StringIO to BytesIO

@daschkin

This comment has been minimized.

Copy link

daschkin commented Jun 11, 2018

Hello,
thank you a lot for this useful flask-app. I have a question:
If I run the app, then images in the same directory as app.py-file are displayed on website without any problems. If I change a directory to other path (not a subpath of current project), the app can lists the files, but doesn't display it. Can it be a rights issue? Or can you give me a hint, how I can solve this issue?
I thank you in advance for your help!

@eddie4

This comment has been minimized.

Copy link

eddie4 commented Jul 15, 2018

Thanks for this. I had to fix some indent stuff and a thing in the template. Have fun with it.

ps. replace if not filename.endswith('.jpg'): with you're extension

import os
from flask import Flask, Response, request, abort, render_template_string, send_from_directory
from PIL import Image
import StringIO

app = Flask(__name__)

WIDTH = 640
HEIGHT = 360

TEMPLATE = '''
<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8" />
    <style>
body {
    margin: 0;
    background-color: #333;
}
.image {
    display: block;
    margin: 2em auto;
    background-color: #444;
    box-shadow: 0 0 10px rgba(0,0,0,0.3);
}
img {
    display: block;
}
    </style>
    <script src="https://code.jquery.com/jquery-1.10.2.min.js" charset="utf-8"></script>
    <script src="http://luis-almeida.github.io/unveil/jquery.unveil.min.js" charset="utf-8"></script>
    <script>
$(document).ready(function() {
    $('img').unveil(1000);
});
    </script>
</head>
<body>
    {% for image in images %}
        <a class="image" href="{{ image.src }}" style="width: {{ image.width }}px; height: {{ image.height }}px">
            <img src="{{ image.src }}" data-src="{{ image.src }}?w={{ image.width }}&amp;h={{ image.height }}" width="{{ image.width }}" height="{{ image.height }}" />
        </a>
    {% endfor %}
</body>
'''

@app.route('/<path:filename>')
def image(filename):
    try:
        w = int(request.args['w'])
        h = int(request.args['h'])
    except (KeyError, ValueError):
        return send_from_directory('.', filename)

    try:
        im = Image.open(filename)
        im.thumbnail((w, h), Image.ANTIALIAS)
        io = StringIO.StringIO()
        im.save(io, format='JPEG')
        return Response(io.getvalue(), mimetype='image/jpeg')

    except IOError:
        abort(404)

    return send_from_directory('.', filename)

@app.route('/')
def index():
    images = []
    for root, dirs, files in os.walk('.'):
        files.sort()
        for filename in [os.path.join(root, name) for name in files]:
            if not filename.endswith('.jpg'):
                continue
            im = Image.open(filename)
            w, h = im.size
            aspect = 1.0*w/h
            print filename
            if aspect > 1.0*WIDTH/HEIGHT:
                width = min(w, WIDTH)
                height = width/aspect
            else:
                height = min(h, HEIGHT)
                width = height*aspect
            images.append({
                'width': int(width),
                'height': int(height),
                'src': filename
            })
    return render_template_string(TEMPLATE, **{
        'images': images
    })

if __name__ == '__main__':
    app.run(host="127.0.0.1", port=3000)
@adv-ai-tech

This comment has been minimized.

Copy link

adv-ai-tech commented Oct 15, 2018

Extremely Thanks for the code. I had been trying this for past 6 hours!!

@roman-ku

This comment has been minimized.

Copy link

roman-ku commented Jan 1, 2019

After having trouble with all the scripts posted so far I made my own. Python 3.5+ compatible.

Here are the changes I had to make:

  • Change import Image to from PIL import Image
  • Change import StringIO to from io import BytesIO
  • Change io = StringIO.StringIO() to io = BytesIO()
  • Change $('img').unveil(1000); to $('img').unveil();
  • Change <script src="http://luis-almeida.github.io/unveil/jquery.unveil.min.js" charset="utf-8"></script> to <script src="jquery.unveil.js" charset="utf-8"></script>
  • Download the jquery.unveil.js script and place it in the same file as the server.py

You can find the updated code in my gist

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.