Very Simple Image Gallery With Python Flask (Free Download)

Welcome to a tutorial on how to create a very simple online image gallery with Python Flask. So you want to share some images online, but don’t want to go through all the “brain damage” stuff? Well, here’s how to create a very simple one – Read on!

 

TABLE OF CONTENTS

 

 

DOWNLOAD & NOTES

Here is the download link to the example code, so you don’t have to copy-paste everything.

 

EXAMPLE CODE DOWNLOAD

Source code on GitHub Gist

Just click on “download zip” or do a git clone. I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

SORRY FOR THE ADS...

But someone has to pay the bills, and sponsors are paying for it. I insist on not turning Code Boxx into a "paid scripts" business, and I don't "block people with Adblock". Every little bit of support helps.

Buy Me A Coffee Code Boxx eBooks

 

 

 

 

QUICK SETUP

  • Create a virtual environment virtualenv venv and activate it – venv\Scripts\activate (Windows) venv/bin/activate (Linux/Mac)
  • Install required libraries – pip install flask
  • For those who are new, the default Flask folders are –
    • static Public files (JS/CSS/images/videos/audio)
    • templates HTML pages

 

PART 1) FLASK SERVER

S1_server.py
# (A) INIT
# (A1) LOAD REQUIRED PACKAGES
import os, glob
from flask import Flask, render_template

# (A2) FLASK SETTINGS + INIT
HOST_NAME = "localhost"
HOST_PORT = 80
PATH_BASE = os.path.dirname(os.path.abspath(__file__))
PATH_STATIC = os.path.join(PATH_BASE, "static")
app = Flask(__name__)
app.debug = True

# (B) GET ALL IMAGES
images = []
for ext in ("jpg", "png", "gif", "webp"):
  for img in glob.iglob(PATH_STATIC + "/*." + ext):
    images.append(os.path.basename(img))

# (C) GALLERY PAGE
@app.route("/")
def index():
  return render_template("S2A_gallery.html", images=images)

# (D) START!
if __name__ == "__main__":
  app.run(HOST_NAME, HOST_PORT)

First, we will start with the Flask HTTP server itself. This should be pretty self-explanatory once you trace through it:

  • (B) Get all the images in the default static/ folder.
  • (C) Pass the list of images to the gallery page.

That’s pretty much everything to the “server”.

 

 

PART 2) GALLERY PAGE

2A) THE HTML

templates/S2A_gallery.html
<div class="gallery">
  {% for img in images: %}
  <figure>
    <img src="static/{{img}}">
    <figcaption>{{img}}</figcaption>
  </figure>
  {% endfor %}
</div>

In the gallery page, we loop through the list of images and generate the respective <img> tags.

 

2B) THE CSS

static/S2B_gallery.css
/* (A) GALLERY CONTAINER */
/* (A1) BIG SCREENS - 3 IMAGES PER ROW */
.gallery {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-gap: 10px;
  max-width: 1200px;
  margin: 0 auto;
}

/* (A2) SMALL SCREENS - 2 IMAGES PER ROW */
@media screen and (max-width: 640px) {
  .gallery { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* (B) THUMBNAILS & CAPTION */
.gallery figure {
  margin: 0;
  border: 1px solid #cdcdcd;
  background: #000;
}
.gallery img {
  width: 100%;
  height: 200px;
  object-fit: cover; /* fill | contain | cover | scale-down */
  cursor: pointer;
}
.gallery figcaption {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 1.1em;
  text-align: center;
  color: #fff;
  padding: 5px 10px;
}

/* (C) FULLSCREEN IMAGE */
.gallery img.full {
  position: fixed;
  top: 0; left: 0; z-index: 999;
  width: 100vw; height: 100vh;
  object-fit: contain; /* fill | contain | cover | scale-down */
  background: #fff;
}

No need to panic, just walk through section by section.

  • (A) grid-template-columns: repeat(N, minmax(0, 1fr)) We set 3 images per row on big screens, and 2 images on small screens.
  • (B) Styles for the image and caption. Just take note of object-fit: cover, this is the resize behavior for the thumbnails. Feel free to switch around and see which one works for you.
  • (C) When the user clicks on an image, this will set the image to fill up the entire window.

 

 

2C) THE JAVASCRIPT

static/S2C_gallery.js
window.addEventListener("DOMContentLoaded", () => {
  // (A) GET ALL IMAGES
  var all = document.querySelectorAll(".gallery img");

  // (B) CLICK ON IMAGE TO TOGGLE FULLSCREEN
  if (all.length>0) { for (let img of all) {
    img.onclick = () => img.classList.toggle("full");
  }}
});

A final bit of Javascript to drive “click on image to show in fullscreen”. That is, toggle a full CSS class on the selected image. Yep, the end.

 

 

EXTRAS

That’s all for the tutorial, and here is a small section on some extras and links that may be useful to you.

 

EXTRA) SORTING THE IMAGES

S1_server.py
# ASCENDING ORDER
images.sort()

# DESCENDING ORDER
images.sort(reverse=True)

As you can see, we loop through jpg, png, gif, webp and put the image files into the list images. Just use the sort() function to sort in ascending or descending order. If you need “very specific sort order” – Do a “python list custom sort” search on the Internet on your own… Or this tutorial will never end.

 

EXTRA) CATEGORIES OR SECTIONS

Quick pseudo-code and idea:

  • Create multiple sub-folders in static – static/CAT1, static/CAT2, etc…
  • Modify S1_server.py.
    • Use a dictionary, not a list – images = { CAT1 : [], CAT2 : [] }
    • for (cat in ("CAT1", "CAT2")): EXTRACT IMAGES AS USUAL - images[cat].append(IMG)
  • Modify S2A_gallery.html
    • for cat in images: <h1>{{ cat }}</h1>
    • <div class="gallery">{{ for img in cat: draw <img> as usual }}</div>

 

 

LINKS & REFERENCES

 

THE END

Thank you for reading, and we have come to the end. I hope that it has helped you to better understand, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!

Leave a Comment

Your email address will not be published. Required fields are marked *