Saturday, January 23, 2010

Python - Easy jQuery lightBox Gallery

If you ever have to put images up on the internet, I recommend using the excellent jQuery plugin lightBox.

Not long ago, a relative asked me to help her with her website. It was made by the previous webmaster using Microsoft Publisher, and was a pain to maintain. Updating the site was especially cumbersome when she needed several images put up in a gallery. It took a long time to resize all of the images and put them in a table - normally around an hour or more. I rewrote the site in PHP and created a neat tool to automatically create a lightBox gallery for me - all I needed to do was drag and drop the folder with the original images in it onto the script file and I had my gallery ready to go! I thought I should share the script for those who may find it useful.

Fist off, however, you will need to install the Python Image Library (PIL). This handles the resizing part of the script.
You will also need jQuery included on your page, as well as everything needed for lightBox.

Once you have that set up, you should be able to use my script: (I don't like the "all catching" except, but it was useful for debugging)

import os
from PIL import Image
import sys
import glob

try:
base_dir = '<insert the full path to the root directory of your site (eg. c:\\sites\\myawesomesite\\)>'
img_dir = base_dir + '<insert the folder where you keep your images (based off the base_dir defined above (eg. \\images\\)>'
thumbs_dir = img_dir + '<insert the folder where you want the thumbnails placed, relative to the images dir defined above (eg. thumbs\\)>'
originals_dir = img_dir + '<insert the folder where you want the originals placed, relative to the images dir defined above (eg. originals\\)>'
web_base_path = '<put the relative URL path to the images directory (eg. /images/)>'
web_thumbs_path = web_base_path + '<put the relative URL path to the thumbs directory (relative to the images dir defined above) (eg. thumbs/)>'

temp_gallery_file = base_dir + '<put the name of the file where you want the gallery code to be stored (eg. TEMP_GALLERY_FILE.html)>'

column_amount = 3 # Put how many columns wide you want the gallery to be

img_display = """\t\t<td>
<div class="image">
<a href="{0}" title="">
<img src="{1}" alt="" />
</a>
<span class="description"></span>
</div>
<br />
</td>
"""

if len(sys.argv) == 1:
sys.exit(1)

resource = sys.argv[1]

# Default width, if it is less, than the old width is used.
thumb_width = 200
max_orignal_width = 700

# Keep the aspect ration (based on the width of the image)
def aspectRatioSize(desired_width, original_size):
original_width = original_size[0] + .0
original_height = original_size[1] + .0
return (desired_width, desired_width * (original_height / original_width))

def getNextAvailableName(folder, img_name, ext):
index = 1
while os.path.exists(folder + img_name + '_' + str(index) + ext):
index += 1
return img_name + '_' + str(index)+ ext

gallery_file = open(temp_gallery_file, "w")

gallery_file.write("<div class=\"gallery\">\n")
gallery_file.write("<table>\n")
gallery_file.write("\t<tr>\n")

base_image_name = os.path.basename(resource)
images = [image for image in glob.glob(resource + "/*.*")]
# Loop through all images in directory, make thumbs and resize the original
for index, image in enumerate(images):
index += 1
print image
img_name, ext = os.path.splitext(os.path.basename(image))
im = Image.open(image)
img_size = im.size
thumb_name = getNextAvailableName(thumbs_dir, base_image_name, ext)
modified_large_name = getNextAvailableName(img_dir, base_image_name , ext)
original_name = getNextAvailableName(originals_dir, base_image_name, ext)

# Thumbnail
thumb = im.resize(aspectRatioSize(thumb_width, img_size), Image.ANTIALIAS)
thumb.save(thumbs_dir + thumb_name)

# Modified Large image
modified_large = im.resize(aspectRatioSize(max_orignal_width, img_size), Image.ANTIALIAS)
modified_large.save(img_dir + modified_large_name)

# Original
im.save(originals_dir + original_name)

if index != 1 and index % column_amount == 1:
gallery_file.write("\t<tr>\n")

gallery_file.write(img_display.format(web_base_path + modified_large_name, web_thumbs_path + thumb_name))

if not index % column_amount:
gallery_file.write("\t</tr>\n")

if index % column_amount > 0:
gallery_file.write("\t</tr>\n")

gallery_file.write("</table>\n")
gallery_file.write("</div>")


gallery_file.close()
except Exception as e:
print e
raw_input()



I also use the following CSS to make the gallery, once created, look the way I want.


.gallery .image {
margin: 0 auto;
text-align: center;
vertical-align: top;
}

.gallery .image .description {
font-size: 11px;
color: #000066;
text-align: center;
display: block;
line-height: normal !important;
}

.gallery td {
vertical-align: top;
}

.gallery table {
margin: 0 auto;
width: 90%
}

.gallery img {
border: none;
}


Once you have all your paths defined correctly, you can use the script by simply dragging the folder with the pictures you want in your gallery onto the script. Keep in mind, that in the current script, it will rename the pictures based on the name of the folder they are in (folder_name_1, folder_name_2, folder_name_3...). I needed something like this to avoid name collisions (it checks to make sure the name is unique).

Once the script finishes, the HTML that the script creates will be in the TEMP_GALLERY_FILE.html file (or whatever you named it). Copy and paste that into the site you want the gallery to be, and you are good to go.

I will be posting a demonstration video shortly.