Movie Trailer Image Flash By

Find out why the . goes before the /

Moderator: Paul Tuersley

Post Reply
User avatar
Atomic
Posts: 157
Joined: April 30th, 2007, 5:55 am
Location: United States, Ohio

Hi All,

I am trying to create the often seen look, in movie trailers, when a series of images flash by really fast.

I have modified Byon Nash's code to get me part of the way. Essentially, create a blank comp, then run the script and browse to a folder of images or footage. The script will create a layer out of each item in the folder and do a quick fade in and fade out on the layer.

This is done in linear time. All layers are the same length. But in movies trailers, there is often a logrithmic acceleration of the diaplay of images so they speed up as more and more are displayed.

I would like to modify this script so the length and placement of each layer reflects that logrithmic acceleration. But I don't know the math.

If anyone has tome to check it out, I'd appreciate the help.

Thanks

Code: Select all

 //Import Section By Byron Nash 10/2004
 //Revised 12/03/2007 Atom

 /* 
  This script imports a folder of images and sequences them in a predestined comp.
 It also sets ALL comps in the project to be the length of the new sequenced comp.
 This is useful if you are versioning a bunch of images into the same graphic bed.
 
 It also also animates the fade in and fade out for each layer.
 
 Instructions:
 1. Make sure you have a project with a comp at the very top. Put a "1" in front of the name if need be to keep it the first object in the list.
 2. Run script
 3. Choose a folder of files when prompted
 
  Just to clarify, this script runs in passes, so it will import a series of image, then create layers from that import. 
  Because this script operates on an existing comp, it does no know the name of the comp, so it references the first object in the project window as the comp.
  Consider this, you create default comp called "Comp 1" then you import a series of images froma folder. The folder contains an image called "blueprint.jpg". 
  Now blueprint.jpg is above Comp 1 in the project list and the script will try to operate on the JPG as if it were a comp. 
  This is what causes the error if you do not put a 1 in front of the comp name. You might want to put a zero. 
  If an image comes in with a 0 instead of a 1 as it's first character you could also error out.
  It's not perfect, but it took me a while to figure this out so I thought I'd mention why it will error out and how to avoid this.
  
  Limitation/ Flaws:
	I already mentioned the naming of the comp flaw in this script.
	I have hard coded the comp size and height to 720x480.
	The duration of each imported image is given 5 seconds, you can adjust this by changing the variable, below.
	The frame rate is calculated at 29.97 fps so if you are using another rate please change this value as well.
	The import will also fail if the images in the folder have numbers prefixing their filename.
 */
 {
 // create undo group
app.beginUndoGroup("Import and Sequence");

//Ask the user for a folder whose contents are to be imported
var targetFolder = folderGetDialog("Import Items from Folder..."); //returns a folder or null
if (targetFolder) 
{
	// if no project open, create a new project to toss the files into. [23839]
	if (!app.project) {app.newProject();}

	function processFile (theFile) 
	{
		try {
			var importOptions = new ImportOptions (theFile); //create a variable containing ImportOptions
			importSafeWithError (importOptions);
		} catch( error ) {
			// eat errors.
		}
	}
	
	function testForSequence (files)
	{
		var searcher = new RegExp ("[0-9]+");
		var movieFileSearcher = new RegExp ("(mov|avi|mpg)$", "i");
		var parseResults = new Array;
		
		//test that we have a sequence, stop parsing after 10 files
		for (x = 0; (x < files.length) & x < 10; x++) 
		{ 
			var movieFileResult = movieFileSearcher.exec(files[x].name);
			if (! movieFileResult) 
			{
				var currentResult = searcher.exec(files[x].name);
				//regular expressions return null if no match was found
				//otherwise they return an array with the following information:
				//array[0] = the matched string
				//array[1..n] = the matched capturing parentheses
			
				if (currentResult) { //we have a match - the string contains numbers
					//the match of those numbers is stored in the array[1]
					//take that number and save it into parseResults
					parseResults[parseResults.length] = currentResult[0];
				}
				else {
					parseResults[parseResults.length] = null;
				}
			}
			else {
				parseResults[parseResults.length] = null;
			}
		}
		
		//if all the files we just went through have a number in their file names, 
		//assume they are part of a sequence & return the first file
		
		var result = null;
		for (i = 0; i < parseResults.length; ++i) {
			if (parseResults[i]) {
				if (! result) {
					result = files[i];		
				}	
			} else {
				//case in which a file name did not contain a number
				result = null;
				break;
			}
		}
		return result;
	}

	function importSafeWithError (importOptions) 
	{
		try { 
			app.project.importFile (importOptions);
		} catch (error) {
			alert(error.toString() + importOptions.file.fsName);
		}
	}

	function processFolder(theFolder) 
	{
		var files = theFolder.getFiles(); //Get an array of files in the target folder
			
		//test whether theFolder contains a sequence
		var sequenceStartFile = testForSequence(files);
		
		//if it does contain a sequence, import the sequence
		if (sequenceStartFile) {
			try {
				var importOptions = new ImportOptions (sequenceStartFile); //create a variable containing ImportOptions
				
				importOptions.sequence = true;
				//importOptions.forceAlphabetical = true; //un-comment this if you want to force alpha order by default
				importSafeWithError (importOptions);
			} catch (error) {
			
			}
		}
		
		//otherwise, import the files and recurse
		//Go through the array and set each element to singleFile, then run the following
		for (index in files) 
		{ 
			if (files[index] instanceof File) {
				if (! sequenceStartFile) { //if file is already part of a sequence, don't import it individually
					processFile (files[index]); //calls the processFile function above
				}
			}
			if (files[index] instanceof Folder) {
				processFolder (files[index]); // recursion
			}
		}
	}
	processFolder(targetFolder);
}

//Script begins here.
var logoSel = app.project.selection;				//set selected import items to an array
var logoComp = app.project.item(1);				//select the logo comp
var compW = 720; 							// comp width
var compH = 480; 							// comp height
var perImageDuration= 30;						//Frames divided by frame rate equals seconds.
logoComp.duration = perImageDuration/29.97 			//set comp length to 1 second

//loop through and add layers to comp
for (i=0; i < logoSel.length; i++)
{			
	//Add to logo comp
	if(logoSel[i] instanceof FootageItem)
	{								//test to be sure it's not a comp or folder
		var lcoll = logoComp.layers;			//variable for collection of layer objects in logoComp
		lcoll.add(logoSel[i]);				//add layer
		//alert (logoSel[i].name);
	}	
}
//At this point, all imported items are in the project window.

//Now we must add them to the comp.
var curIn = 0;							//initialize in point variable
var i = 1;								//collection items start at 1.
//Loop through layers
do
{
	//Add footage layer.
	var curLayer = lcoll[i];
        curLayer.startTime = curIn;				//set in point 
        var curOut = curLayer.outPoint;			//set out
	//Auto animate the fade in and out for this layer.
	myOpacity= curLayer.property("opacity"); 
	myOpacity.setValueAtTime(curIn,0); 
	myOpacity.setValueAtTime(curIn + 0.25,100); 
	myOpacity.setValueAtTime(curOut - 0.25,100);	//Effectively creates a hold frame, can cause problems on interlace footage.
	myOpacity.setValueAtTime(curOut,0); 
	curIn = curOut 						//new in point equals old out point.
	//alert (curLayer.name);
	i++;
}while(i<=lcoll.length);
        
// Set Final Comp to correct length.
logoComp.duration = (i-1) * logoComp.duration		//set comp end to reflect the new length.
compDur = logoComp.duration;				//set variable for all comps
var stuff = app.project.items;				//get collection of project items
for (i=1; i <= stuff.length; i++)
{//loop through project looking for our original comp item that was selected before we ran this script.
	if(stuff[i] instanceof CompItem) 
	{//check for comp
		stuff[i].duration = compDur;			//set comp length
	}
} 
alert("Finished Importing and Sequencing of Images. Be sure to save the project as a new name.")
app.endUndoGroup();
}	
bradshaw1965
Posts: 98
Joined: March 14th, 2006, 2:16 pm
Location: Atlanta, GA
Contact:

Would it make sense to set the comp up linearly and then set a time remap on the placed comp perhaps with some controls to adjust the remap?

Dale
Dale Bradshaw
Technology Director | Primal Screen
creative-workflow-hacks.com
Atlanta, GA
User avatar
Atomic
Posts: 157
Joined: April 30th, 2007, 5:55 am
Location: United States, Ohio

Bradshaw 1965,

That is exactly what I thought.

But what expression would I apply to the slider to make it start slow then speed up?
bradshaw1965
Posts: 98
Joined: March 14th, 2006, 2:16 pm
Location: Atlanta, GA
Contact:

I don't think you really need a post-processing expression. Just give the user the option of what kind of easing, enable time remap, set that ease with user input at x time, and then use the time graph in the graph editor to adjust the time remap.
Dale Bradshaw
Technology Director | Primal Screen
creative-workflow-hacks.com
Atlanta, GA
Post Reply