Skip to main content
January 3, 2013
Answered

Stacking video frames

  • January 3, 2013
  • 2 replies
  • 3616 views

Hi everybody,

I need a bit of help getting started with a script for photoshop CS6.

I've seen that it's possible (Even if not supported) to have a script open individual video frames.  What I need is to take each frame and apply it with lighten blend mode to the frames before it.

The result should be a single image image with a single layer (JPG, PNG, TIFF, whatever...) .

This shouldn't be too complex of a script, right?  I don't remember much about photoshop scripting, so any help would be welcome!

Thanks!

This topic has been closed for replies.
Correct answer Michael_L_Hale

If I understand what you want this should do all but the final save. Note it could take a long time if there are a lot of frames.

// this requires a document with a video layer be the activeDocument

// and the video layer be the activeLayer. It also requires the timeline panel be visible

var vidDoc = app.activeDocument;

var dupDoc = vidDoc.duplicate();

dupDoc.flatten();

app.activeDocument = vidDoc;

var numerOfFrames = GetFrameCount();

for( var f =0; f< numerOfFrames; f++ ){

    GotoNextFrame();

    vidDoc.selection.selectAll();

    executeAction( charIDToTypeID( "CpTL" ), undefined, DialogModes.NO );// jump frame to new layer

    vidDoc.activeLayer.duplicate(dupDoc);

    vidDoc.activeLayer.remove();

    app.activeDocument = dupDoc;

    dupDoc.activeLayer.blendMode = BlendMode.LIGHTEN;

    dupDoc.flatten();

    app.activeDocument = vidDoc;

}

function GetFrameCount(){

    var ref = new ActionReference();

     ref.putProperty( charIDToTypeID( 'Prpr' ), stringIDToTypeID( "frameCount" ) );

     ref.putClass( stringIDToTypeID( "timeline" ) );

     var desc = new ActionDescriptor();

     desc.putReference( charIDToTypeID( 'null' ), ref );

     var resultDesc = executeAction( charIDToTypeID( 'getd' ), desc, DialogModes.NO );

    

     return resultDesc.getInteger( stringIDToTypeID( "frameCount" ) );

};

function GotoNextFrame() {

     var thatWorked = undefined;

     try {

          var desc = new ActionDescriptor();

          var ref = new ActionReference();

          ref.putEnumerated( charIDToTypeID( "Mn  " ), charIDToTypeID( "MnIt" ), stringIDToTypeID( "timelineGoToNextFrame" ) );

          desc.putReference( charIDToTypeID( "null" ), ref );

          executeAction( charIDToTypeID( "slct" ), desc, DialogModes.NO );

          thatWorked = true;

     }

     catch(e) {

          thatWorked = false;

          alert('All frames are processed.');

     }

     return thatWorked;

};

2 replies

c.pfaffenbichler
Community Expert
Community Expert
January 3, 2013

I've seen that it's possible (Even if not supported) to have a script open individual video frames.

Where have you seen this?

January 3, 2013

Here:

http://forums.adobe.com/thread/726287

It's from 2010, so that would be CS4 or CS5, but I'm hoping it could be done with CS6.

I do have access to CS5 too, if necessary.

Michael_L_HaleCorrect answer
Inspiring
January 4, 2013

If I understand what you want this should do all but the final save. Note it could take a long time if there are a lot of frames.

// this requires a document with a video layer be the activeDocument

// and the video layer be the activeLayer. It also requires the timeline panel be visible

var vidDoc = app.activeDocument;

var dupDoc = vidDoc.duplicate();

dupDoc.flatten();

app.activeDocument = vidDoc;

var numerOfFrames = GetFrameCount();

for( var f =0; f< numerOfFrames; f++ ){

    GotoNextFrame();

    vidDoc.selection.selectAll();

    executeAction( charIDToTypeID( "CpTL" ), undefined, DialogModes.NO );// jump frame to new layer

    vidDoc.activeLayer.duplicate(dupDoc);

    vidDoc.activeLayer.remove();

    app.activeDocument = dupDoc;

    dupDoc.activeLayer.blendMode = BlendMode.LIGHTEN;

    dupDoc.flatten();

    app.activeDocument = vidDoc;

}

function GetFrameCount(){

    var ref = new ActionReference();

     ref.putProperty( charIDToTypeID( 'Prpr' ), stringIDToTypeID( "frameCount" ) );

     ref.putClass( stringIDToTypeID( "timeline" ) );

     var desc = new ActionDescriptor();

     desc.putReference( charIDToTypeID( 'null' ), ref );

     var resultDesc = executeAction( charIDToTypeID( 'getd' ), desc, DialogModes.NO );

    

     return resultDesc.getInteger( stringIDToTypeID( "frameCount" ) );

};

function GotoNextFrame() {

     var thatWorked = undefined;

     try {

          var desc = new ActionDescriptor();

          var ref = new ActionReference();

          ref.putEnumerated( charIDToTypeID( "Mn  " ), charIDToTypeID( "MnIt" ), stringIDToTypeID( "timelineGoToNextFrame" ) );

          desc.putReference( charIDToTypeID( "null" ), ref );

          executeAction( charIDToTypeID( "slct" ), desc, DialogModes.NO );

          thatWorked = true;

     }

     catch(e) {

          thatWorked = false;

          alert('All frames are processed.');

     }

     return thatWorked;

};

c.pfaffenbichler
Community Expert
Community Expert
January 3, 2013

I for one find your explanation unclear.

What do you start with, a stack of numbered images or a file with Layers …?

Could you please post a screenshot or mock-up to illustrate what you are trying to achieve?

January 3, 2013

I suppose a run down of the algorithm might help explain what I need.

I start with an .AVI file.

1) Open first frame as base layer (Layer 0)

2) Open second frame as a new layer (layer 1)

3) Change blend mode of layer 1 to Lighten

4) Flatten image (Again, we have only leyer 0)

5) Repeat 2 to 4 untill last frame

6) Save flattened image.

I end up with a JPG or whatever other image file format.

c.pfaffenbichler
Community Expert
Community Expert
January 3, 2013

Have you tried File > Import > Video Frames to Layers?

Somebody needed help once with digitally simulating film being exposed to a complete movie (so something like a 90-plus-minute exposure) and in that case Layer > Smart Objects > Stack Mode provided a better approach than Blending the Layers directly. This may not at all be what you are after, but I wanted to mention it just in case.