pyimg was written as a learning project. I wanted to clone the functionality of taimg in Python. I chose to recreate taimg because it is something I use frequently and it has very clear requirements.

Written for Python > 2.0 and imagemagick > 6.0

#! /usr/bin/env python
import sys, os, commands, glob
 
def main(args):
    """pyimg: python-based gallery control for Obscura
 
    Usage: pyimage [index|conv] {arguments}
 
    Example: Create image index for current directory
        $ pyimg index "title" "location" "date"
    Example: Call imagemagick to create thumbnails etc
        $ pyimg conv
    """	
 
    # Set conversion options
    options_sq = "-quality 95 -density 72x72 -resize 300 -crop 125x125+20+20 -bordercolor white -border 1x1"
    options_vert = "-quality 100 -density 72x72 -resize x500"
    options_hor = "-quality 100 -density 72x72 -resize 500"
 
    # Set default information
    defaultTechnical = "Canon T70"
    defaultCopyright = "Copyright © 2005, Steve Block"
    
    if args[0] == "index":
        print "Generating index..."
       	write_cat(defaultTechnical, defaultCopyright, args[1:])
    elif args[0] == "print":
        print_cat()
    elif args[0] == "conv":
        print "Converting images..."
        convert(options_sq, options_vert, options_hor)
    else:
       	print main.__doc__
 
 
class Cat(file):
    "Manipulate a catfile"
 
    # Writes an individual record to the cat file following the formatting
    # convention used by Obscura
    def write_record(self, thisfile, args, defaultTechnical="Canon T70", \
                     defaultCopyright="Copyright &copy 2005, Steve Block"):
        self.write("%s|%s|%s|%s|%s\n" % (thisfile, args[0], defaultTechnical, \
                defaultCopyright, "|".join(args[1:])))
    # Reads a line from the cat file and returns a tuple containing all the
    # useful information from the file. If the line is blank (last line),
    # return None
    def read_record(self):
        line = self.readline()
        line = line.strip()
        if line != '':
            (filename,title,tech,copy,location,date) = line.split("|")
            return (filename,title,tech,copy,location,date)
        else:
            return None
    # Prints the contents of the cat file to the screen. Unformatted.
    def print_cat(self):
        for line in self.readlines():
            line = line.strip()
            print line.split("|")
 
 
def write_cat(defaultTechnical, defaultCopyright, args):
    """Creates a file named index.cat in the current directory
    
    The index.cat file contains a list of files and attributes for the image
    files in a directory. Each line of the file represents a single jpeg
    image. The format of each line is:
 
    file|title|technical|copyright|location|date
    """
 
    # Check that the right number of arguments has been passed
    if len(args) != 3:
        print main.__doc__
        return -1
    
    # Create and sort a list of jpeg files in the current directory
    files = glob.glob('*.jpg')
    files.sort()
 
    # Take that directory list and create the index.cat file
    this_cat = Cat("index.cat", "w")
    for this_file in files:
        this_cat.write_record(this_file[:-4], args, \
                defaultTechnical, defaultCopyright)
    this_cat.close()
    
 
def print_cat(filename="index.cat"):
    "Reads a cat file and prints the contents."
 
    this_cat = Cat(filename, "r")
    this_cat.print_cat()
    this_cat.close()
 
def convert(opt_s,opt_v,opt_h,filename="index.cat"):
    "Reads a catfile and calls imagemagick to perform conversions"
 
    # Check for existence of the scale directory and create it if it doesn't
    # exist.
    if not os.path.exists("scale"):
        os.mkdir("scale",0755)
 
    # Open the cat file
    this_cat = Cat(filename, "r")
 
    # Read the first record from the file, and begin a loop that will continue
    # until the last record in the file is reached. The loop will create
    # pathnames and call imagemagick's convert script to do the file
    # conversions.
    record = this_cat.read_record()
    while record != None:
        (filename,title,tech,copy,location,date) = record
        record = this_cat.read_record()
 
        # Generate filenames
        obs_file = "scale/%s-obs.jpg" % filename
        sq_file = "scale/%s-sq.jpg" % filename
 
        # Call convert to create the square file if it doesn't already exist
        if not os.path.exists(sq_file):
            commands.getstatusoutput("convert %s.jpg %s %s" % \
                    (filename, opt_s, sq_file))
 
        # Determine the image dimensions
        (w,h) = jpgSize("%s.jpg" % filename)
 
        # Perform conversion
        if not os.path.exists(obs_file):
            if h > w:
                print "Making %s, original %i x %i, height mode." % \
                        (obs_file, w, h)
                commands.getstatusoutput("convert '%s.jpg' %s '%s'" % \
                        (filename, opt_v, obs_file))
            else:
                print "Making %s, original %i x %i, width mode." % \
                        (obs_file, w, h)
                commands.getstatusoutput("convert '%s.jpg' %s '%s'" % \
                        (filename, opt_h, obs_file))
 
        
def jpgSize(jpeg):
    markers = '\xc0\xc1\xc2\xc3\xc5\xc6\xc7\xc9\xca\xcb\xcd\xce\xcf'
 
    # Check image format. Make sure it is a jpg
    image = file(jpeg, mode="rb")
    if image.read(2) != '\xff\xd8':
        image.close()
        return -1
 
    while 1:
        frame_header = image.read(2)
        if frame_header == '':
            image.close()
            return -1
        boundary, marker = frame_header
        if boundary != '\xff':
            image.close()
            return -1
 
        found = 1
        for this_marker in markers:
            if marker == this_marker:
                found = 0
                break
        if found == 0:
            break
 
        frame_length = image.read(2)
        if frame_length == '':
            image.close()
            return -1
        frame_length = s2n(frame_length)
        image.seek(frame_length - 2,1)
 
    image.seek(3,1)
    height = s2n(image.read(2))
    width = s2n(image.read(2))
 
    image.close()
        
    return (width,height)
 
def s2n(string):
    x = 0
    for c in string:
        x = (x << 8) | ord(c)
    return x
 
 
if __name__ == "__main__":
    if len(sys.argv) > 1:
        main(sys.argv[1:])
    else:
        print main.__doc__
 
debian/pyimg.txt · Last modified: 2005/02/22 00:40 by 71.34.173.30
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki