views:

785

answers:

4

Hi, I am trying to write my first real python function that does something real. What i want to accomplish is searching a given folder, and then open all images and merging them together so they make a filmstrip image. Imagine 5 images stacked on top of eachother in one image.

I have this code now, which should be pretty much ok, but propably needs some modification:

import os
import Image

def filmstripOfImages():

    imgpath = '/path/here/'
    files = glob.glob(imgpath + '*.jpg')

    imgwidth = files[0].size[0]
    imgheight = files[0].size[1]
    totalheight = imgheight * len(files)

    filename = 'filmstrip.jpg'
    filmstrip_url = imgpath + filename

    # Create the new image. The background doesn't have to be white
    white = (255,255,255)
    filmtripimage = Image.new('RGB',(imgwidth, totalheight),white)  
    row = 0
    for file in files:
        img = Image.open(file)

        left = 0
        right = left + imgwidth
        upper = row*imgheight
        lower = upper + imgheight
        box = (left,upper,right,lower)
        row += 1

        filmstripimage.paste(img, box)
    try:
        filmstripimage.save(filename, 'jpg', quality=90, optimize=1)
    except:
        filmstripimage.save(miniature_filename, 'jpg', quality=90)")

How do i modify this so that it saves the new filmstrip.jpg in the same directory as I loaded the images from? And it probably has some things that are missing or wrong, anybody got a clue?

Related question: How to generate a filmstrip image in python from a folder of images?

+1  A: 

I think if you change your try section to this:

filmstripimage.save(filmstrip_url, 'jpg', quality=90, optimize=1)
Harley
+1  A: 

In the case you are not joking there are several problems with your script e.g. glob.glob() returns list of filenames (string objects, not Image objects) therefore files[0].size[0] will not work.

J.F. Sebastian
+1  A: 

as J. F. Sebastian mentioned, glob does not return image objects... but also:

As it is right now, the script assumes the images in the folder are all the same size and shape. This is not often a safe assumption to make.

So for both of those reasons, you'll need to open the images before you can determine their size. Once you open it you should set the width, and scale the images to that width so there is no empty space.

Also, you didn't set miniature_filename anywhere in the script.

Jiaaro
+2  A: 

It is not an answer to your question, but It might be helpful:

#!/usr/bin/env python
import Image

def makefilmstrip(images, mode='RGB', color='white'):
    """Return a combined (filmstripped, each on top of the other) image of the images.

    """
    width  = max(img.size[0] for img in images)
    height = sum(img.size[1] for img in images)

    image = Image.new(mode, (width, height), color) 

    left, upper = 0, 0
    for img in images:
        image.paste(img, (left, upper))
        upper += img.size[1]

    return image

if __name__=='__main__':
    # Here's how it could be used:
    from glob import glob
    from optparse import OptionParser

    # process command-line args
    parser = OptionParser()
    parser.add_option("-o", "--output", dest="file",
                      help="write combined image to OUTPUT")

    options, filepatterns = parser.parse_args()
    outfilename = options.file

    filenames = []
    for files in map(glob, filepatterns):
        if files:
            filenames += files

    # construct image
    images = map(Image.open, filenames)    
    img = makefilmstrip(images)
    img.save(outfilename)

Example:

$ python filmstrip.py -o output.jpg *.jpg
J.F. Sebastian
Thanks, this solution seems clever, but when i try to implement it, and run the map(Image.open,...) I get an error:"type object 'Image' has no attribute 'open'"Any clue to why this is happening?
Espen Christensen
@Espen Christensen: Check that `Image = type(Image)` is *NOT* present in your code. Copy-paste my code. What is the result?
J.F. Sebastian