Playing a series of images

Feed an input from another node instead of its widget, make file names from numbers, loop with iterate, and change a node's code.

The folder cartoonMovie holds 101 frames, crnCartoon0000.png to crnCartoon0100.png. We will turn the image viewer of the previous tutorial into a movie player. Start from your image viewer, or open cartoon0: an image viewer.

File names in widgets are relative to the network's folder, so cartoonMovie/... works wherever the folder is.

A file name from a dial

  1. Drag a Filename node (Standard > Input). It makes a file name from a number and a format, with Python's % formatting: set its format to cartoonMovie/crnCartoon%04d.png (%04d: the number on 4 digits).
  2. Now, how do we bring its output to Read Image, whose file name comes from its widget? Right-click Read Image's image file widget and choose Unbind (show the port). The widget goes, and filename becomes a port.
    The menu of Read Image's file widget, with Unbind (show the port)
  3. Connect Filename's filename output to Read Image's filename. Filename stops: its number input is required and has no data yet.
  4. Drag a DialInt (Standard > Input) and connect its value to Filename's number. Turning the dial now makes a file name, reads the image, scales it and shows it.
DialInt, Filename, Read Image, Scale and Show Image, frame 6 shown
The dial chooses the frame. DialInt at 6 gives cartoonMovie/crnCartoon0006.png.
Checkpoint cartoon0b: a file name from a dial

To give the widget back, right-click the filename port and choose Rebind widget.

Loop with iterate

Rather than turning a dial, let's play the frames one after the other.

  1. Delete the DialInt. Drag an iterate node (Standard > Python) and connect its oneItem output to Filename's number.
  2. iterate needs a list to loop over: drag a range node (Standard > Python), set it from 0 to 99 by 1, and connect its data to iterate's listToLoopOver.
  3. Press Run. iterate sends the numbers one at a time, and runs the nodes below it for each one: the movie plays in the Show Image panel. Stop stops it after the current frame.
range, iterate, Filename, Read Image, Scale and Show Image; range's parameters in the column
iterate over a range. range is selected: its from, to and step are in the parameter column. iterate is a scheduling node: it runs what is below it once per item.
Checkpoint cartoon1: iterate over a range

A widget can be in the node, or only in the parameter column: right-click range's step widget and choose Show in the panel only. Uncheck run on change while you set several widgets, so the movie does not start each time.

Try this: change range to play every other frame.

A list of files

Instead of making file names from numbers, we can list the files.

  1. Delete range and Filename. Drag a Filelist node (Standard > Input), set its directory to cartoonMovie and its match string to crnCartoon*.png (or crnCartoon????.png; the wildcards are the shell's).
  2. Connect its filelist to iterate's listToLoopOver, and iterate's oneItem straight to Read Image's filename.
  3. Run. The frames may play out of order: the files come in the order the folder lists them. The list is a Python list, which has a sort method: insert a call method node (Standard > Python) between Filelist and iterate and type sort in its signature.
Checkpoint cartoon3: sort the list with call method

Don't we have a way to change the Python code instead? Delete the call method node, double-click Filelist to open its code, and add values.sort() after the line that makes the list:

    try:
        values = glob.glob(match_str)
        values.sort()
        filenames = [ os.path.join(directory, x) for x in values ]
        self.outputData(filelist=filenames)

Press Save and run. Save the network (File > Save), close it and open it again: the changed code is saved with the network, as every change made to a node is.

Filelist, iterate, Read Image, Scale and Show Image
iterate over a file list. Filelist's code sorts the names.
Checkpoint cartoon1b: iterate over a file list

Exercise: play it backwards

Add an input port named reverse to the Filelist node, with a check button widget. When it is checked, the list is reversed and the movie plays backwards.

  1. Select Filelist; in the parameter column open Add a port: input, name reverse, type boolean, and check widget. Press Add port.
  2. The compute function gets a reverse argument. Edit the code:
            values.sort()
            if reverse:
                values.reverse()