Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

« Newer Snippets
Older Snippets »
Showing 1-7 of 7 total  RSS 

Latest and greatest directory thumbnailer

This does basically the same thing as my original code (http://www.bigbold.com/snippets/posts/show/1296), but significantly faster. Thumbnail sizes are cached between executions, and they could probably be kept around as static data in the mod_python environment if I could figure out how.

Also note that the thumbnailing function no longer returns a complete page, but rather a single table (compatible with either HTML or XHTML). This allows the code to be embedded into something like a photo gallery.

A simple function is shown at the end of this snippet, to set up thumbnailing with mod_python on apache.

from os.path import join,exists
from os import stat,mkdir,listdir
import re
from PIL import Image
import cPickle

images_per_row = 5
max_width,max_height = 150,150

search = re.compile("(.*\.jpe?g$)|(.*\.png$)|(.*\.gif$)", re.IGNORECASE)

def list_directory(path):
  thumbnail_size_cache = {}
  thumbnail_size_cache_changed = False

  return_value = []
  dir_list = listdir(path)
  images = [file for file in dir_list if search.match(file)]

  if len(images) < 1:
    return ''

  # Interesting directories
  thumbsdir = join(path, ".thumbnails")

  # Try to load the size cache from a file
  cache_file_path = join(thumbsdir, "thumbnail_size_cache.dat")
  if exists (cache_file_path):
    cache_file = open(cache_file_path, "r")
    thumbnail_size_cache = cPickle.load(cache_file)
    cache_file.close()

  images.sort()
  return_value.append('<table width="100%" border="0"><tr>\n')
  row_template = '<td><a href="%(name)s"><img src=".thumbnails/%(name)s" alt="%(name)s" width="%(width)d" height="%(height)d"/></a>'

  # If the thumbnail directory does not exist, create it
  if not exists(thumbsdir):
    mkdir(thumbsdir)

  image_num = 0
  for image in images:
    image_num += 1

    thumbfile = join(thumbsdir, image)
    filepath = join(path, image)
    width,height = 0,0

    # Check if there is an already-existing thumbnail
    create_new_thumbnail = True
    if exists(thumbfile):
      thumb_stat = stat(thumbfile)
      img_stat = stat(filepath)

      # Check if the thumbnail is newer than the image
      if img_stat.st_mtime < thumb_stat.st_mtime:
        try:
          width,height = thumbnail_size_cache[image]
          create_new_thumbnail = False
        except KeyError:
          pass

    if create_new_thumbnail:
      # Thumbnail the image
      thumbnail = Image.open(filepath)
      thumbnail.thumbnail((max_width, max_height), Image.ANTIALIAS)
      thumbnail.save(thumbfile)
      thumbnail_size_cache[image] = thumbnail.size
      thumbnail_size_cache_changed = True
      width,height = thumbnail.size

    return_value.append(row_template % {'name': image, 'width': width, 'height': height})

    if image_num % images_per_row:
      return_value.append('</td>\n')

    else:
      return_value.append('</td></tr><tr>\n')

  return_value.append("</tr></table>")

  # Save the cache
  if thumbnail_size_cache_changed:
    return_value.append("Saved cache")
    cache_file = open(cache_file_path, "w")
    cPickle.dump(thumbnail_size_cache, cache_file, cPickle.HIGHEST_PROTOCOL)
    cache_file.close()

  return ''.join(return_value)

####################################
### mod_python stuff starts here ###
####################################

from mod_python import apache

html_header = '''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head><title>Directory Listing</title></head>
<body><div>'''

xhtml_header = '''<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml111/DTD/xhtml111.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head><title>Directory Listing</title></head>
<body><div>'''

def handler(req):
  if not os.path.isdir(req.filename):
    file = open(req.filename)
    req.write(file.read())
    return apache.OK

  return_value = []
  # Check for XHTML acceptance
  accept_types = req.headers_in["Accept"].split(",")

  # Don't do any measure of preference for now
  if "application/xhtml+xml" in accept_types:
    # Accepts XHTML
    return_value.append(xhtml_header)
    req.content_type="application/xhtml+xml"
  else:
    # Does not accept XHTML
    return_value.append(html_header)
    req.content_type="text/html"

  return_value.append(list_directory(req.filename))
  return_value.append("</div></body></html>")
  req.write(''.join(return_value))
  return apache.OK

[Multiplatform] Thumbnails of all (gif, jpeg, and png) images in a directory

Thanks Dorrin for your Thumbnailer!
I hope you don't mind, but I did some minor fixes and made your script more portable. Now, you can use it on Windows too.
By the way, as I revealed there is no dependency of "from mod_python import apache", so I removed it.

import os
import re
from PIL import Image

header = '''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head><title>Directory Listing</title></head>
<body>'''
images_per_row = 5
max_width,max_height = 150,150

path = os.path.dirname(__file__)
  
def thumbnail(filename):
  thumbsdir = os.path.join(path, ".thumbnails")
  thumbfile = os.path.join(thumbsdir, filename)
  if os.path.exists(thumbfile):
    return

  if not os.path.exists(thumbsdir):
    os.mkdir(thumbsdir);
    
  filepath = os.path.join(path, filename)
  image = Image.open(filepath)
  image.thumbnail((max_width, max_height), Image.ANTIALIAS)
  image.save(thumbfile)

def index(req):
  return_value = header

  dir_list = os.listdir(path)
  image_list = []

  search = re.compile("(.*\.[Jj][Pp][Ee]?[Gg]$)|(.*\.[Pp][Nn][Gg]$)|(.*\.[Gg][Ii][Ff]$)")

  image_count = 0
  for file in dir_list:
    if search.match(file):
      image_count += 1
      image_list.append(file)

  if image_count > 0:
    image_list.sort()
    num_rows = image_count / images_per_row

    image_num = 0
    return_value += '<table width="100%" border="0"><tr>\n'

    for image in image_list:
      thumbnail(image)
      image_num += 1
      return_value += '<td><a href="' + image + '"><img src=".thumbnails/' + image + '" alt="' + image + '"></a>'

      if image_num % images_per_row:
        return_value += '</td>\n'

      else:
        return_value += '</td></tr><tr>\n'

  return_value += "</table></body></html>"
  return return_value


Here is small test script.
It generates thumbnails with Dorrin's script, then grabs HTML output and writes it to index.html file, so you get nice index page.

import thumbnail
import os

html = thumbnail.index(0)

htmlfile = os.path.join(os.getcwd(), "index.html")
f = open(htmlfile, "w")
f.write(html);
f.close()

Thumbnails of all (gif, jpeg, and png) images in a directory

I've gone with just gif, jpeg, and png for now, but it should be easy enough to add any others that PIL supports - just update the regex.

This code generates a basic page with thumbnails of all images in the directory it is run from. It caches thumbnails in the .thumbnails directory. It requires mod_python and PIL to run, though mod_python can be removed trivially.

from mod_python import apache
import os
import re
from PIL import Image

header = '''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head><title>Directory Listing</title></head>
<body>'''
images_per_row = 5
max_width,max_height = 150,150

path = os.path.dirname(__file__)
  
def thumbnail(filename):
  if os.path.exists(path + "/.thumbnails/" + filename):
    return

  image = Image.open(path + "/" + filename)
  image.thumbnail((max_width, max_height), Image.ANTIALIAS)
  image.save(path + "/.thumbnails/" + filename)

def index(req):
  return_value = header

  dir_list = os.listdir(path)
  image_list = []

  search = re.compile("(.*\.[Jj][Pp][Ee]?[Gg]$)|(.*\.[Pp][Nn][Gg]$)|(.*\.[Gg][Ii][Ff]$)")

  image_count = 0
  for file in dir_list:
    if search.match(file):
      image_count += 1
      image_list.append(file)

  if image_count > 0:
    image_list.sort()
    num_rows = image_count / images_per_row

    image_num = 0
    return_value += '<table width="100%" border="0"><tr>\n'

    for image in image_list:
      thumbnail(image)
      image_num += 1
      return_value += '<td><a href="' + image + '"><img src=".thumbnails/' + image + '" alt="' + image + '"></a>'

      if image_num % images_per_row:
        return_value += '</td>\n'

      else:
        return_value += '</td></tr><tr>\n'

  return_value += "</table></body></html>"
  return return_value

convert a PIL image to a GTK pixbuf

free adaptation of http://slugathon.python-hosting.com/changeset/205

import gtk
import Image

def image2pixbuf(im):  
    file1 = StringIO.StringIO()  
    im.save(file1, "ppm")  
    contents = file1.getvalue()  
    file1.close()  
    loader = gtk.gdk.PixbufLoader("pnm")  
    loader.write(contents, len(contents))  
    pixbuf = loader.get_pixbuf()  
    loader.close()  
    return pixbuf  

convert a GTK pixbuf to a PIL image

import gtk
import Image

def pixbuf2Image(pb):
   width,height = pb.get_width(),pb.get_height()
   return Image.fromstring("RGB",(width,height),pb.get_pixels() )

pb = gtk.gdk.pixbuf_new_from_file( "p20050424_160333.jpg" )
im = pixbuf2Image(pb)
im.save("welldone.jpg", "JPEG",quality=80)

Create Image Thumbnails (Python)

# experiments with the Python Image Library (PIL)

# free from:  http://www.pythonware.com/products/pil/index.htm

# create 128x128 (max size) thumbnails of all JPEG images in the working folder

# Python23 tested    vegaseat    25feb2005


import glob
import Image

# get all the jpg files from the current folder

for infile in glob.glob("*.jpg"):
  im = Image.open(infile)
  # convert to thumbnail image

  im.thumbnail((128, 128), Image.ANTIALIAS)
  # don't save if thumbnail already exists

  if infile[0:2] != "T_":
    # prefix thumbnail file with T_

    im.save("T_" + infile, "JPEG")

Sparkline: from PIL to S60

py_s60 1.1.3 has its drawing API very similar to PIL.
Porting from PIL to S60 is very easy. Here's an example
that I port a sparkline drawing function from
Joe Gregorio's article at xml.com
# modified from  Joe Gregorio's article at
# http://www.xml.com/pub/a/2005/06/22/sparklines.html

from appuifw import *
import e32

lock = e32.Ao_lock()
c = Canvas()
app.body = c
draw = c._draw

red, green, blue, gray = 0xff0000, 0x00ff00, 0x0000ff, 0x777777

def plot_sparkline(results, step=2, height=20, \
    min_m=None, max_m=None, last_m=None, \
    min_color=blue, max_color=green, last_color=red):
    coords = zip(range(1,len(results)*step+1, step), \
       [height - 3  - y/(101.0/(height-4)) for y in results])
    draw.line(coords, gray)
    if min_m:
        min_pt = coords[results.index(min(results))]
        draw.rectangle([min_pt[0]-1, min_pt[1]-1, min_pt[0]+1, min_pt[1]+1], fill=min_color)
    if max_m:
        max_pt = coords[results.index(max(results))]
        draw.rectangle([max_pt[0]-1, max_pt[1]-1, max_pt[0]+1, max_pt[1]+1], fill=max_color)
    if last_m:
        end = coords[-1]
        draw.rectangle([end[0]-1, end[1]-1, end[0]+1, end[1]+1], fill=last_color)


results = [88,84,82,92,82,86,66,82,44,64,66,88,96,80,24,26, \
        14,0,0,26,8,6,6,24,52,66,36,6,10,14,30]
plot_sparkline(results, 3, 30, min_m=1, max_m=1, last_m=1)

app.exit_key_handler = lock.signal
lock.wait()
« Newer Snippets
Older Snippets »
Showing 1-7 of 7 total  RSS