[Basic Operations...] [Table of Contents]

Creating Procedures and more Complex Effects with Images


The commands from SEQUENCE TRANSFORMS can be used in Tcl procedure to create more complex effects. For instance, a common video editing operation is assembly, when two or more sequences are connected and written. The following Rivl fragment Preview extracts n seconds off the beginning of each movie in a list of movies. The call to seq_new creates an empty sequence for the return value. The loop repeatedly extracts the first n seconds from each sequence in movieList and appends it to result, which is returned.

proc preview {movieList n} {
	#Create an empty sequence
	set result [seq_new]
	foreach movie $movieList {
		#Grab the first n seconds off the next movie
		set chunk [seq_crop $movie 0.0 $n]
		#Concatenate the segment onto the result
		seq_concat! result $chunk
	}
	return $result
}


Probably the most important single command when creating procedures applied to sequences is seq_map.Seq_map executes a given script for each image of a sequence and assembles the resulting images into a new sequence. Seq_map is similar to "mapcar" in Lisp. Consider the command

seq_map $clip {im_fade %1 0.5}
Seq_map substitutes the handle of the current image wherever %l appears in the script. Thus, this command returns a new sequence containing the images in clip faded by half.

Sometimes, rather than applying the exact same effect to each image, it is desirable to vary the effect over time. For example, consider the fade-to-black effect. This effect can be achieved by calling to im_fade on each image in the sequence with a paramer that decrease over time. In this case, seq_map must call a procedure with a parameter that indicates the time of the image being modified. To this end, seq_map performs the following additional subtitutions:

  • %1: Substitute the current image
  • %t: Substitute the time stamp of the current image, in seconds
  • %l: Substitute the length of the sequence in seconds
  • %p: Substitute the relative time of the current imge: %t divided by %l

    Using this mechanism, fade-to-black can be expressed

    seq_map $clip {im_fade %l [expr 1-%p]}
    If clip is 21 frames long, this expands into the following series of commands:
    im_fade image1 1.00
    im_fade image2 0.95
    im_fade image3 0.90
    ...
    im_fade image20 0.05
    im_fade image21 0.00
    
    The resulting images are concatenated into a new sequence, resulting in the desired fade-out visual effect.

    When combined with sequence operations, seq_map simplifies the expression of effects that are often used in transitions between two parts of a movie. For example, the following Rivl procedure Transition connects two sequences with a transition:

    proc Transition {transition movieA movieB duration} {
    	set lengthA [seq_length $movieA]
    	set lengthB [seq_length $movieB]
    
    	# Untouched parts of first and second movie
    	set begin [seq_crop $movieA 0.0 [expr $lengthA-$duration]]
    	set end [seq_crop $movieB $duration $lengthB]
    
    	# Apply timed effect to end of first movie; overlay with
    	# beginning of second movie
    	set mid1 [seq_crop $movieA [expr $lengthA-$duration] $lengthA]
    	set mid2 [seq_crop $movieB 0.0 $duration]
    	set middle [seq_overlay [seq_map $mid1 $transition] $mid2]
    
    	seq_concat $begin $middle $end
    	}
    
    The first parameter, transition, is a script passed to seq_map. MovieA and movieB are the two sequences to be joined, and duration is the time (in seconds) to apply the transition effect. For example, Transition fadeOut jack jill 5 connects two sequences jack and jill with a five second fade.


    [Top]