Skip to main content
Participant
June 7, 2020
Question

How can I save every layer merged with the one below? To show retouching progress on a gif

  • June 7, 2020
  • 2 replies
  • 1168 views

I would like to automate saving every layer of my image merged with the ones before.

 

Meaning: the first layer is one saved file, then layer 1 & 2 merged is another saved file, then layer 3 merged with the ones before (1&2) and so on.

 

So in the future, I can make it a gif/video to show the retouching progress

 

Thank you for your help!

This topic has been closed for replies.

2 replies

c.pfaffenbichler
Community Expert
Community Expert
June 7, 2020

 

Edit: A screenshot of a layered file and the corresponding gif the Script produces. 

 

 

// create gif with the layers added one at a time;
// 2020, use it at your own risk;
if (app.documents.length > 0) {
var thisDoc = app.activeDocument;
try {
var theName = thisDoc.name.match(/(.*)\.[^\.]+$/)[1];
var thePath = thisDoc.path
}
catch (e) {
var theName = thisDoc.name;
var thePath = "~/Desktop"
};
// make duplicate;
var myDocument = thisDoc.duplicate();
// =======================================================
var idmakeFrameAnimation = stringIDToTypeID( "makeFrameAnimation" );
executeAction( idmakeFrameAnimation, undefined, DialogModes.NO );
setFrameDelay (0.2);
// hide all but lowermost layer;
hideOthers (myDocument.layers[myDocument.layers.length - 1], myDocument);
// collect layers;
var theLayers = collectLayersBounds();
// add frames;
for (var a = 0; a < theLayers.length; a++) {
// =======================================================
var desc2 = new ActionDescriptor();
var ref1 = new ActionReference();
ref1.putEnumerated( stringIDToTypeID( "animationFrameClass" ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );
desc2.putReference( charIDToTypeID( "null" ), ref1 );
executeAction( charIDToTypeID( "Dplc" ), desc2, DialogModes.NO );
// show;
showLayer (theLayers[a][1], false);
};
// export;
exportGif (thePath, theName+".gif");
// close copy;
myDocument.close(SaveOptions.DONOTSAVECHANGES)
};
////////////////////////////////////
////// set framedelay //////
function setFrameDelay (theDelay) {
try {
var desc14 = new ActionDescriptor();
var ref7 = new ActionReference();
ref7.putEnumerated(stringIDToTypeID( "animationFrameClass" ), charIDToTypeID( "Ordn"), charIDToTypeID( "Trgt" ));
desc14.putReference( charIDToTypeID( "null" ), ref7 );
var desc15 = new ActionDescriptor();
desc15.putDouble(stringIDToTypeID( "animationFrameDelay" ), theDelay );
desc14.putObject( charIDToTypeID( "T   " ), stringIDToTypeID( "animationFrameClass" ), desc15 );
executeAction( charIDToTypeID( "setd" ), desc14, DialogModes.NO );
return true
} catch (e) {return false}
};
////// collect layers //////
function collectLayersBounds () {
// the file;
var myDocument = app.activeDocument;
// get number of layers;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process the layers;
var theLayers = new Array;
for (var m = 0; m <= theNumber; m++) {
try {
var ref = new ActionReference();
ref.putIndex( charIDToTypeID( "Lyr " ), m);
var layerDesc = executeActionGet(ref);
var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
// if group collect values;
if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true) {
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
var theBounds = layerDesc.getObjectValue(stringIDToTypeID("bounds"));
var theseBounds = [theBounds.getUnitDoubleValue(stringIDToTypeID("left")), theBounds.getUnitDoubleValue(stringIDToTypeID("top")), theBounds.getUnitDoubleValue(stringIDToTypeID("right")), theBounds.getUnitDoubleValue(stringIDToTypeID("bottom"))];
theLayers.push([theName, theID, theseBounds])
};
}
catch (e) {};
};
return theLayers
};
 ////// toggle visibility of others //////
function hideOthers (theLayer, myDocument) {
myDocument.activeLayer = theLayer;
// =======================================================
var desc10 = new ActionDescriptor();
var list4 = new ActionList();
var ref7 = new ActionReference();
ref7.putEnumerated( charIDToTypeID( "Lyr " ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );
list4.putReference( ref7 );
desc10.putList( charIDToTypeID( "null" ), list4 );
desc10.putBoolean( charIDToTypeID( "TglO" ), true );
executeAction( charIDToTypeID( "Shw " ), desc10, DialogModes.NO );
};
////// show layer //////
function showLayer (theID, showOrHide) {
if (showOrHide == false) {var idHd = charIDToTypeID( "Shw " )}
else {var idHd = charIDToTypeID( "Hd  " )};
var desc2 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var list1 = new ActionList();
var ref1 = new ActionReference();
ref1.putIdentifier(charIDToTypeID( "Lyr " ), theID);
list1.putReference( ref1 );
desc2.putList( idnull, list1 );
executeAction( idHd, desc2, DialogModes.NO );
};
////// export gif //////
function exportGif (thePath, theName) {
var webOptions = new ExportOptionsSaveForWeb();
webOptions.format = SaveDocumentType.COMPUSERVEGIF;
webOptions.transparency = true;
webOptions.interlaced = 0;
webOptions.includeProfile = false;
webOptions.optimized = true;
activeDocument.exportDocument(new File(thePath+"/"+theName), ExportType.SAVEFORWEB, webOptions);
};

edited

 

 

 

johnjoeparrot
Known Participant
November 4, 2024

Hello @c.pfaffenbichler 
Any tips for updateing the code to save the gif layer by layer? Instead of seeing all the previous layers in the animation it just shows each layer as a frame

Thanks!

Stephen Marsh
Community Expert
Community Expert
November 4, 2024

What is the layer content?

 

Is it a series of layers stacked on top of each other, where each layer is in the same canvas area? If so, this would just be a regular animation wouldn't it? An action can automate the creation of such a timeline setup and save or export to GIF.

 

Or is it a horizontal or vertical layout as per the animated example from @c.pfaffenbichler ?

c.pfaffenbichler
Community Expert
Community Expert
June 7, 2020

If you expect to process files of varying numbers of Layers Actions would likely run into problems so you need to use a Script. 

How good are you with JavaScript? 

 

Are all the Layers top-level or are Groups involved? 

Please provide a file or at least a screenshot including the Layers Panel.