Sleepy Weim

Python: Picture Tiles that Change

If you jumped straight here, I get it. This code is for randomly selecting a photo from a directory, and saving it to a predefined location and filename. Very sexy, of course, so you couldn’t wait to get here and start running with it!

Feel free to play with the code, break things, and then go back and read the main page where I explain why I do certain things. 😉

There are four main strings to define:

  • path_src: This is the root folder where your pictures are stored
  • path_dst: This is where the selected pictures will be saved; for me this is in my web folder structure
  • thePath: the subfolder you need to pass into the function; in theory, this can be an empty string, I think; I haven’t tried that
  • theFile: the filename (without extension) that will be used to save the picture

I’m showing my code as I use it since it shows how to just call multiple iterations from one script, how to find different classifications of photos (based solely on your folder/organization structure), and how to specify the folder names.

import os
import random
from random import shuffle
from shutil import copyfile
from PIL import Image
from PIL import ExifTags

# path: The complete path; function will navigate up one folder
def stepUp(path):
    pathLength = len(path)
    loc = path.rfind('/')
    if pathLength == (loc + 1):
        #print 'Found the trailing slash.  Remove and repeat.'
        tempPath = path[:(-1 * (pathLength - loc))]
        loc = tempPath.rfind('/')
        pathLength = len(tempPath)

    tempPath = path[:(-1 * (pathLength - loc))]
    #print 'New Path: ', tempPath
    return tempPath

# img: the image object we want to inspect and manipulate
def correctRotation(img):
    # Check orientation, and rotate if needed
    # This looks for EXIF data in the file and determines if the camera was rotated when the picture was taken
    # This can throw off the check we do for portrait vs landscape
    for orientation in ExifTags.TAGS.keys() : 
        if ExifTags.TAGS[orientation]=='Orientation' : break 


        if   exif[orientation] == 3 : 
            img=img.rotate(180, expand=True)
            #print ' -- 180'
        elif exif[orientation] == 6 : 
            img=img.rotate(270, expand=True)
            #print ' -- 270'
        elif exif[orientation] == 8 : 
            img=img.rotate(90, expand=True)
            #print ' -- 90'
        print " -- File contains no EXIF data."
    return img

# thePath: the subfolder we want to search in; the full path will be 'path_src + thePath'
# theFile: the filename we will use to save the file out to, into the the 'path_dst' location
def selectImageFrom(thePath, theFile):
    # Get the combined path and the list of files
    print 'New Loop: ', thePath
    path_temp = path_src + thePath
    files = os.listdir(path_temp)
    # Loop in case we keep getting invalid files
    for x in range (0, 200):
        #print ' -- count: ', x, file

        file = random.choice(files)
        if not files: print "-- WARNING: File list is now empty."
        # Check if we have a file or a directory
        if os.path.isdir(path_temp + file):
            print " -- found directory: PATH: ", path_temp, " FILE: ",file
            # If dir, then descend into subdir
            # -- Adding and ignoring system folders that are bad
            if file != '@eaDir':
                path_temp = path_temp + file + '/'
                files = os.listdir(path_temp)
            # If file, then check the extension and process, or restart the loop
            filename, file_extension = os.path.splitext(file)

            if file_extension.lower() == '.jpg' or file_extension.lower() == '.jpeg' or file_extension.lower() == '.png':
                # The types of files we are looking for
                img = + file)
                img = correctRotation(img)

                # For our display, we only want landscape pictures for better display
                width, height = img.size
                if width >= height:
                    print " -- Good File: Landscape ", path_temp + file, ' Width: ', width, 'Height: ', height
                    print " --  Bad File: Portrait  ", path_temp + file, ' Width: ', width, 'Height: ', height
                # The types of files we are NOT looking for
                print " --  Bad File: Not JPG   ", path_temp + file
        if not files: 
            #print ' -- !!!! You should move up a directory at this point. !!!!'
            path_temp = stepUp(path_temp)
            files = os.listdir(path_temp)

    newFile = theFile + file_extension.lower()
    newPath = path_dst + newFile
        #copyfile(os.path.join(path_temp, file), newPath)
        print " -- No file was selected."


# Path Source: The main location where all the files live; all my photo folders are under this location
# Path Destination: the location in the web folder structure I will use for my URLs
path_src = '/volume1/files/GoogleDrive/Pictures/'
path_dst = '/volume1/web/actiontiles/'

# Each directory I am using; in my case I have them organized by events
# You can skip this step, but for my 'friends' folder I call it twice, so you can define a folder once but reference it many times later
src_running = '# Running/'
src_disney = 'Disney/'
src_friends = '# Parties, Events, Trips/'

# We could just put the directories straight into the function calls, but I prefer to define them above
# Since each filename will need to be different, I add them as strings right into the function call
selectImageFrom(src_running, 'running')
selectImageFrom(src_disney, 'disney')
selectImageFrom(src_friends, 'friends')
selectImageFrom(src_friends, 'friends2')

Leave a Reply