views:

268

answers:

2

Hello people,

I'm using a python generator function to provide me with a list of images in the current directory. However I see the function is giving out the entire list twice instead of one time and I have no idea why. I'm using the Python PIL library to create batch thumbnails.

Can anyone point me in the right direction?

Thanks in advance!

Script:


import os
import sys
import Image

class ThumbnailGenerator:
    def __init__(self, width, height, image_path, thumb_path):
        self.width = width
        self.height = height
        self.image_path = image_path
        self.thumb_path = "%s%s%s" % (self.image_path, os.sep, thumb_path)

    def __call__(self):
        self.__create_thumbnail_dir()

        for filename, image in self.__generate_image_list():
            try:
                thumbnail = "%s%s%s" % (self.thumb_path, os.sep, filename)
                image.thumbnail((self.width, self.height))
                image.save(thumbnail, 'JPEG')
                print "Thumbnail gemaakt voor: %s" % filename
            except IOError:
                print "Fout: thumbnail kon niet gemaakt worden voor: %s" % filename

    def __generate_image_list(self):
        for dirpath, dirnames, filenames in os.walk(self.image_path):
            count = 0
            for filename in filenames:
                try:
                    image = Image.open(filename)
                    print '=========', count, filename
                    count += 1
                    yield (filename, image)
                except IOError:
                    pass

    def __create_thumbnail_dir(self):
        try:
            os.mkdir(self.thumb_path)
        except OSError as exception:
            print "Fout: %s" % exception

if __name__ == '__main__':
    try:
        thumbnail_generator = ThumbnailGenerator(80, 80, '.', 'thumbs')
        thumbnail_generator()
    except KeyboardInterrupt:
        print 'Programma gestopt'
The output of the script at this moment (with some test images) is:
========= 0 124415main_image_feature_380a_ys_full.jpg
Thumbnail gemaakt voor: 124415main_image_feature_380a_ys_full.jpg
========= 1 60130main_image_feature_182_jwfull.jpg
Thumbnail gemaakt voor: 60130main_image_feature_182_jwfull.jpg
========= 2 assetImage.jpg
Thumbnail gemaakt voor: assetImage.jpg
========= 3 devcon-c1-image.gif
Fout: thumbnail kon niet gemaakt worden voor: devcon-c1-image.gif
========= 4 image-646313.jpg
Thumbnail gemaakt voor: image-646313.jpg
========= 5 Image-Schloss_Nymphenburg_Munich_CC.jpg
Thumbnail gemaakt voor: Image-Schloss_Nymphenburg_Munich_CC.jpg
========= 6 image1w.jpg
Thumbnail gemaakt voor: image1w.jpg
========= 7 New%20Image.jpg
Thumbnail gemaakt voor: New%20Image.jpg
========= 8 samsung-gx20-image.jpg
Thumbnail gemaakt voor: samsung-gx20-image.jpg
========= 9 samsung-image.jpg
Thumbnail gemaakt voor: samsung-image.jpg
========= 0 124415main_image_feature_380a_ys_full.jpg
Thumbnail gemaakt voor: 124415main_image_feature_380a_ys_full.jpg
========= 1 60130main_image_feature_182_jwfull.jpg
Thumbnail gemaakt voor: 60130main_image_feature_182_jwfull.jpg
========= 2 assetImage.jpg
Thumbnail gemaakt voor: assetImage.jpg
========= 3 devcon-c1-image.gif
Fout: thumbnail kon niet gemaakt worden voor: devcon-c1-image.gif
========= 4 image-646313.jpg
Thumbnail gemaakt voor: image-646313.jpg
========= 5 Image-Schloss_Nymphenburg_Munich_CC.jpg
Thumbnail gemaakt voor: Image-Schloss_Nymphenburg_Munich_CC.jpg
========= 6 image1w.jpg
Thumbnail gemaakt voor: image1w.jpg
========= 7 New%20Image.jpg
Thumbnail gemaakt voor: New%20Image.jpg
========= 8 samsung-gx20-image.jpg
Thumbnail gemaakt voor: samsung-gx20-image.jpg
========= 9 samsung-image.jpg
Thumbnail gemaakt voor: samsung-image.jpg

While it should be:

========= 0 124415main_image_feature_380a_ys_full.jpg
Thumbnail gemaakt voor: 124415main_image_feature_380a_ys_full.jpg
========= 1 60130main_image_feature_182_jwfull.jpg
Thumbnail gemaakt voor: 60130main_image_feature_182_jwfull.jpg
========= 2 assetImage.jpg
Thumbnail gemaakt voor: assetImage.jpg
========= 3 devcon-c1-image.gif
Fout: thumbnail kon niet gemaakt worden voor: devcon-c1-image.gif
========= 4 image-646313.jpg
Thumbnail gemaakt voor: image-646313.jpg
========= 5 Image-Schloss_Nymphenburg_Munich_CC.jpg
Thumbnail gemaakt voor: Image-Schloss_Nymphenburg_Munich_CC.jpg
========= 6 image1w.jpg
Thumbnail gemaakt voor: image1w.jpg
========= 7 New%20Image.jpg
Thumbnail gemaakt voor: New%20Image.jpg
========= 8 samsung-gx20-image.jpg
Thumbnail gemaakt voor: samsung-gx20-image.jpg
========= 9 samsung-image.jpg
Thumbnail gemaakt voor: samsung-image.jpg

As you can see the generator function is returning the list twice (I verified it and it gets called only once).

Any help would be appriciated!

@heikogerlach: os.walk cannot find the thumbnails as I'm walking the filenames of the current directory and the thumbnails get written to a sub-folder of the current directory called 'thumb'. The list is generated before writing the thumbnails to the 'thumb' dir and I verified (using WinPDB) that the thumbnails are not included in the list.

@S.Lott: Thanks for the advice. os.path.join fixed the problem.

Thanks to you all for helping me solve the problem!

A: 

Your thumbnails are in a subdirectory of self.image_path and have the same name as the original image. Can you check if walk finds the thumnails as you create them? Just print the path of the image together with the name.

unbeknown
os.walk cannot find the thumbnails as I'm walking the filenames of the current directory and the thumbnails get written to a sub-folder of the current directory called 'thumb'. The list is generated before writing the thumbnails to the 'thumb' dir and I verified (using WinPDB) that the thumbnails are not included in the list.
@python-newbe: os.walk() descends into subdirectories, too. And there is no fixed list. Its a generator that can just generate more filenames after you start using them.
unbeknown
+3  A: 

In your debugging, print the full path. I think you're walking the thumbs subdirectory after you walk the . directory.

Also.

class ThumbnailGenerator( object ):

Usually works out better in the long run.

Please do NOT use __ in front of your method names (generate_image_list and create_thumbnail_dir).

Do not use "%s%s%s" % (self.image_path, os.sep, thumb_path) to make path names, use os.path.join.

S.Lott
How come subclassing the class from object is preferred?
Paolo Bergantino
@Paolo: it defines new-style classes. See http://www.python.org/doc/newstyle/
nosklo