from string import Template #PictureGallery.py, This version released on 26th July 2012 #This allows you to creates a gallery of pictures from a file of image names. #you need to install the Image module also known as the Python Imaging Library # from here http://www.pythonware.com/products/pil/ #you need to edit the test code after the "if __name__=="__main__" #to do: load images+information as JSON files import os.path import os import re import Image def combine_dicts(dict1,dict2): return dict(dict1.items()+dict2.items()) def file_extension(path): pos = path.rfind(".") if pos == -1: return "" else: return path[pos:].lower() def without_extension(path): pos = path.rfind(".") if pos == -1: return path else: return path[:pos] def get_image_base(path): return without_extension(os.path.basename(path)) def get_image_size(image_path): "returns a tuple of (with,height) giving the real size of the image in pixels" im = Image.open(image_path) size = im.size return size class PictureGallery(object): def __init__(self, title): self.title = title #use this for title bar #self.nb_levels = nb_levels #the number of zoom levels: to do self.index_header_template = Template(''' $title

$h1_title

$click_message $extra_message
''') self.index_footer = """
""" self.image_page_template = Template(''' $image_base
$BeforePrev Prev $after_prev | IndexHome |$before_next Next $after_next

Copyright © $year,

$image_footer

''') self.bg_colour = "black"#default self.text_colour = "grey" self.h1_title = title #default self.year="2012" self.std_suffix = "_std"#default string to add to end of image name self.std_size = [1500,1500]#default size of box containing standard image, this is a recommended size, the real one may be different self.thumb_suffix = "_thm"#default self.thumb_size = [150,150]#default size of box containing thumb, this is a recommended size, the real one may be different self.click_message = "Click on thumbnails" self.extra_message = "" self.overwrite = False#by default forbid overwriting a file by one with the same name during generation self.thumb_template = Template('') self.before_thumb_template = Template('') self.after_thumb='\r\n' self.images = [] #have to load them def load_from_directory(self, dirpath): "loads all image files in a given directory, in that order" self.images.extend([os.path.join(dirpath,entry) for entry in os.listdir(dirpath) if file_extension(entry) in [".jpg",".tif",".bmp"]]) def load_from_text_file(self, path): """loads the image file names from a text file, each image path is on a separate line. You call this repeatedly to add more image files. ignores empty lines and lines beginning with #. """ ifh = open(path,"r") lines = ifh.readlines() ifh.close() self.images.append([line.strip() for line in lines if len(line)>0 and line[0]!='#']) def reduce_image(self,path_original, size_reduced, path_reduced): "use size_reduced as a box to reduce the images" if os.path.exists(path_reduced) and not self.overwrite: return #print "reduce_image(",original,size,reduced,")" statv = os.stat(path_original) atime = statv.st_atime mtime = statv.st_mtime if path_reduced == path_original: print "reduce_image called on same input and output",original sys.exit(1) img = Image.open(path_original) img.thumbnail(size_reduced,Image.ANTIALIAS) img.save(path_reduced,"JPEG") os.utime(path_reduced,(atime,mtime))#copy time return mtime #you will be likely to use this one def set_h1_title(self, h1_title): self.h1_title = h1_title def set_std_size(size): self.std_size= size # size of box containing standard image, this is a recommended size, the real one may be different def set_thumb_size(size): self.thumb_size= size # size of box containing standard image, this is a recommended size, the real one may be different def set_bg_colour(self, bg_colour): self.bg_color = bg_colour #it's unlikely you will use these: def set_thumb_suffix(suffix): self.thumb_suffix = suffix def set_std_suffix(suffix): self.std_suffix = suffix def write(self,target_directory): self.target_dir = target_directory "Writes both the HTML of the index, the individual HTML pages perm image and the image files" ofh = open(os.path.join(target_directory,"index.htm"),"w") header = self.index_header_template.substitute(self.__dict__) footer = self.index_footer ofh.write(header) image_counter = 1 nb_images = len(self.images) for image_path in self.images: print "image_path",image_path single_image_page = SingleImagePage(image_path,self,image_counter,nb_images - image_counter) single_image_page.write_images()#write images first so we know real sizes of thumbs and standard images single_image_page.write_HTML() ofh.write(self.before_thumb_template.substitute(combine_dicts(self.__dict__, single_image_page.__dict__))) ofh.write(self.thumb_template.substitute(combine_dicts(self.__dict__, single_image_page.__dict__))) ofh.write(self.after_thumb) image_counter += 1 ofh.write(footer) ofh.close() class SingleImagePage(object): def __init__(self,image_path,parent,imageNb,nbLeft): self.image_path=image_path self.image_base = get_image_base(image_path) #print "image_base" ,self.image_base self.parent = parent self.image_nb = imageNb if self.image_nb == 1: self.BeforePrev = "" self.after_prev = "" else: self.BeforePrev = ''%(get_image_base(parent.images[imageNb -2])+self.parent.std_suffix) self.after_prev = "" self.nb_left = nbLeft if self.nb_left== 0: self.before_next = "" self.after_next = "" else: self.before_next = ''%(get_image_base(parent.images[imageNb])+self.parent.std_suffix) self.after_next = "" self.image_footer="" def get_thumb_path(self): return os.path.join(self.parent.target_dir,self.image_base+self.parent.thumb_suffix+".jpg") def get_std_path(self): return os.path.join(self.parent.target_dir,self.image_base+self.parent.std_suffix+".jpg") def write_HTML(self): "writes the html file to display the standard image" ofh = open(os.path.join(self.parent.target_dir,self.image_base+self.parent.std_suffix+".htm"),"w") page_string = self.parent.image_page_template.substitute(combine_dicts(self.__dict__ ,self.parent.__dict__ )) ofh.write(page_string) ofh.close() def write_images(self): "writes thumb and standard size images" thumb_target_path = self.get_thumb_path() self.parent.reduce_image(self.image_path,self.parent.thumb_size,thumb_target_path) thumb_size = get_image_size(thumb_target_path) self.thumb_width = thumb_size[0] self.thumb_height = thumb_size[1] std_target_path = self.get_std_path() self.parent.reduce_image(self.image_path,self.parent.std_size,std_target_path) std_size = get_image_size(std_target_path) self.std_width = std_size[0] self.std_height = std_size[1] #below is sample test code if __name__ == "__main__": g = PictureGallery("Craon") g.set_h1_title("Le chateau de Craon") #g.image_page_template.substitute(g.__dict__, image_base="",BeforePrev="",after_prev="",before_next="",after_next="",image_footer="") g.load_from_directory(r"E:\Mes images\Chateaux\Craon\BestOf") g.write(r"E:\Mes images\Chateaux\Craon\BestOf\HTML")#the directory had to be created first