Using the Parameter Parsing Utility for Custom Parameters

Problem

Sometimes you want to do several tasks that differ only slightly. Instead of creating a separate script for each task, we can create a more general script that uses parameters for the details that differ.

With all your great photos of Patches, you want to create a simple LOLcat script that will add two text strings to a photo, one at the top, and one at the bottom, both centered. You have already picked out the perfect font, etc, but each photo will have different text, and all the photos have different names. You also want the option of specifying the font size for the bottom text, in case it is too long to fit at the default size.

Solution

import sys       # Deadline sends script parameters as command line arguments, sys.argv.
from DraftParamParser import * # Draft helper functions for processing arguments.

# The argument name/type pairs we're expecting.
expectedTypes = dict()
expectedTypes['inFile'] = '<string>'
expectedTypes['outFile'] = '<string>'
expectedTypes['topText'] = '<string>'
expectedTypes['bottomText'] = '<string>'
# We don't specify the bottom text size parameter here, because it is optional.
# We will use ParseCommandLine_TypeAgnostic to check for it.

# Parse the command line arguments.
params = ParseCommandLine( expectedTypes, sys.argv ) # params now contains a
        # dictionary of the parameters initialized to values from the arguments.
inFile = params['inFile'] # The photo we wish to use for the lolcat image.
outFile = params['outFile'] # Where to save the lolcat image.
topText = params['topText'] # Text to place at the top of the image.
bottomText = params['bottomText'] # Text to place at the bottom of the image.

image = Draft.Image.ReadFromFile( inFile ) # Read in the photo to use for our LOLcat.

# Set up how you want the text to appear.
textInfo = Draft.AnnotationInfo()
textInfo.PointSize = 48

# Create the image for the top text.
topTextImage = Draft.Image.CreateAnnotation( topText, textInfo )

edgeOffset = 20.0 / image.height  # Position text 20 pixels from the top and bottom.

# Add the top text to the output image.
image.CompositeWithPositionAndAnchor( topTextImage, 0.5, 1.0 - edgeOffset,
        Draft.Anchor.North, Draft.CompositeOperator.OverCompositeOp )

# Check to see if we specified the optional bottom text size.
paramsA = ParseCommandLine_TypeAgnostic( sys.argv )
if ( 'bottomTextSize' in paramsA ) :
    # We must convert non-string types ourselves for type agnostic parameters.
    textInfo.PointSize = int( paramsA[ 'bottomTextSize' ] )

# Create the image for the bottom text.
bottomTextImage = Draft.Image.CreateAnnotation( bottomText, textInfo )

# Add the bottom text to the output image.
image.CompositeWithPositionAndAnchor( bottomTextImage, 0.5, edgeOffset,
        Draft.Anchor.South, Draft.CompositeOperator.OverCompositeOp )

image.WriteToFile( outFile )  # Save the completed LOLcat image.

Discussion

To run this script from the command line, assuming it is in a file called LOLcat.py, we can use:

> python lolcat.py inFile="Patches.jpg" outFile="PatchesLOL.jpg" topText="LOL" \
  bottomText="I AM PATCHES"

or:

> python lolcat.py inFile="Patches.jpg" outFile="PatchesLOL.jpg" topText="I AM CAT" \
  bottomText="HEAR ME ROAR!!!" 'bottomTextSize'=88

Valid types for the expected parameter types include '<string>', '<int>' and '<float>'.

DraftParamParser contains other useful functions. For example, to convert the parameter from a string to a list of frames, use:

frames = FrameRangeToFrames( params['frameList'] )  # Get a list of individual frames

To create a filename from a filename pattern and frame number, use:

currFilename = ReplaceFilenameHashesWithNumber( filePattern, currFrameNum )

If we expect to be using the same parameter values multiple times, we can store them in a file and parse them using:

params = ParseParamFile( expectedTypes, paramFile )