Skip to content

Instantly share code, notes, and snippets.

@nihlton
Last active December 28, 2020 10:26
Show Gist options
  • Save nihlton/a40c3bb3497330bf143f2fb9f6a1d16b to your computer and use it in GitHub Desktop.
Save nihlton/a40c3bb3497330bf143f2fb9f6a1d16b to your computer and use it in GitHub Desktop.
Python: Serve Images + thumbnails list as JSON. Generate missing thumbnails on the fly.
#!/usr/bin/python
from urlparse import urlparse, parse_qs
from PIL import Image
import os
import json
print "Content-Type: application/json"
print ""
response_object = {}
image_dimensions = {}
thumb_dimensions = {}
IMAGES_PATH = '/images/'
THUMBS_PATH = '/image_thumbs/'
MAX_THUMB_SIZE = (500, 500)
base_path = os.environ['DOCUMENT_ROOT']
media_path = '/media/'
queryParams = parse_qs(urlparse(os.environ['REQUEST_URI']).query)
def thumbnail_image(in_path, out_path):
global MAX_THUMB_SIZE
image = Image.open(in_path)
width, height = image.size
cropped = image.crop((int(width * .15), int(height * .15), int(width * .80), int(height * .80)))
cropped.thumbnail(MAX_THUMB_SIZE)
cropped.save(out_path)
def get_image_dimensions(in_path):
image = Image.open(in_path)
width, height = image.size
return { 'width': width, 'height': height }
def web_path(type, format, filename =''):
global media_path
return media_path + type + format + filename
def disk_path(type, format, filename =''):
global base_path
global media_path
return base_path + media_path + type + format + filename
try:
images = [ { \
'thumbs': os.listdir(disk_path(image_type, THUMBS_PATH)), \
'images': os.listdir(disk_path(image_type, IMAGES_PATH)), \
'type': image_type} for image_type in queryParams['type']]
for image_type in images:
image_folder_for_type = disk_path(image_type['type'], IMAGES_PATH)
thumb_folder_for_type = disk_path(image_type['type'], THUMBS_PATH)
for imageFile in image_type['images']:
image_path = image_folder_for_type + imageFile
thumbnail_path = thumb_folder_for_type + imageFile
if not os.path.exists(thumbnail_path):
thumbnail_image(image_path, thumbnail_path)
if 'include-dimensions' in queryParams:
image_dimensions = [ get_image_dimensions(disk_path(image_type['type'], IMAGES_PATH, file)) for file in os.listdir(image_folder_for_type) ]
thumb_dimensions = [ get_image_dimensions(disk_path(image_type['type'], THUMBS_PATH, file)) for file in os.listdir(image_folder_for_type) ] #avoid different sort order
final_images_paths = [ web_path(image_type['type'], IMAGES_PATH, file) for file in os.listdir(image_folder_for_type) ]
final_thumbs_paths = [ web_path(image_type['type'], THUMBS_PATH, file) for file in os.listdir(image_folder_for_type) ] #avoid different sort order
final_tuple = zip(final_images_paths, final_thumbs_paths, image_dimensions, thumb_dimensions)
response_object[image_type['type']] = [ {'image': final_image, \
'thumbnail': final_thumb, \
'imageDimensions': image_dim , \
'thumbDimensions': thumb_dim } for (final_image, final_thumb, image_dim, thumb_dim) in final_tuple ]
else:
final_images_paths = [ web_path(image_type['type'], IMAGES_PATH, file) for file in os.listdir(image_folder_for_type) ]
final_thumbs_paths = [ web_path(image_type['type'], THUMBS_PATH, file) for file in os.listdir(image_folder_for_type) ] #avoid different sort order
final_tuple = zip(final_images_paths, final_thumbs_paths)
response_object[image_type['type']] = [ {'image': final_image, 'thumbnail': final_thumb } for (final_image, final_thumb) in final_tuple ]
print json.dumps(response_object)
except Exception as e:
print json.dumps(e)
@nihlton
Copy link
Author

nihlton commented Apr 21, 2020

now optionally includes image width and height in the JSON images.py?type=some-type&include-dimensions=true.

for performance reasons, i don't know if i'd ask for dimensions in public facing pages if you've got a HUGE directory of images.

need to refactor to only read the os.listdir once... but later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment