Copy link to clipboard
Copied
I have a graphic that I have sent through various generated variations to alter its look and style. I'd like to save a png of all of those different variations, however the only way that I've found to do this is by individually revealing each generation layer and each variation and saving them one-by-one.
I've looked at the built-in Automate and Scripts options, but none of them seem to offer the ability to export layers of an open document, let alone the different variations.
Aside from writing my own script to do this (I don't have the knowledge to do this), is there a way to automate this process that I'm overlooking?
You can try this.
// create png for each variation of generative fill layers;
// 2024, use it at your own risk;
if (app.documents.length > 0) {
var thedoc = activeDocument;
var docName = thedoc.name;
try {
var basename = docName.match(/(.*)\.[^\.]+$/)[1];
var origDocPath = thedoc.fullName;
var docPath = thedoc.path;
}
catch (e) {
var basename = thedoc.name;
var docPath = "~/Desktop"
};
// process layers;
var theSOs = collectSmartObjects ();
f
...
I figured out a different way to do this, so I thought that I would belatedly post it:
/*
Generative Layer Variations to PNG.jsx
v1.0 - 23rd April 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/is-there-a-quot-simple-quot-way-to-export-all-generation-variations/m-p/14442568
*/
#target photoshop
if (app.activeDocument.activeLayer.kind == LayerKind.SMARTOBJECT) {
// If the active layer is a smart object generative fill layer
var ref = new ActionRefe
...
Copy link to clipboard
Copied
Maybe someone else has created a Script for this yet, but Actions etc. just won’t suffice.
Please provide the file or at least meaningful screenshots with the pertinent Panels (Toolbar, Layers, Properties, Options Bar, …) visible.
Copy link to clipboard
Copied
I can't provide the actual graphic (IP reasons), but I've included a redacted graphic, if that helps. The gist is that I've followed this tutorial to generate variations of that graphic in different art styles (watercolor, crayon, oil etc.) into separate layers. For each of these layers, I have dozens of variations on that theme.
So starting from the top, I have the top-most layer enabled then one by one I click through the variation results, quick export as .png, append -001 to the filename, then rinse and repeat on the next variation.
Once I've gone through all of the variations on a layer, I'll hide the top layer and move to the next and go through the same process. There appears to be a 60 generation limit per layer, so I couldn't do as many as I needed on a single layer.
Copy link to clipboard
Copied
So you want all Layers underneath to be included in the exported files? (You didn’t mention hiding the other Layers when you talked about the top-most layer.)
Please provide screenshots that illustrate the »start«-state of the file and the intended results (naturally not all, just a sample).
Copy link to clipboard
Copied
Sorry if my initial explanation wasn't clear. The layers are just groups of variations. So in practical terms, it's really just whatever is the top-most visible layer that is exported. Not that the each export is a combination of layers below it. Hiding the top layer is just the most practical method for me to work through the process manually. The layers are just "batches" of variations, not components of the final graphic.
All layers visible>Quick Export as PNG>Rename with -###>Save>Cycle to variation 2>Quick Export>Rename>Save>Cycle (etc. etc. through 60 variations)
Hide top layer>Quick Export>Rename>Save>Cycle>Quick Export
The start state is, itself, just a single .png exported from Illustrator.
Hopefully the attached helps visualize it better.
Copy link to clipboard
Copied
There are initially 3 generative fill variations stored per layer. An action or script can select each variation in turn on the active layer.
It then comes down to how you wish to output the result... Is it just the selected layer containing generative fill content? Or is it a combination of the generative layer + one or more additional layers?
Would the PNG be saved with the generative fill prompt (layer name) as the file name? Would it be saved with the document name + layer name? What location to save to?
What else that I haven't thought of above?
Copy link to clipboard
Copied
It then comes down to how you wish to output the result... Is it just the selected layer containing generative fill content? Or is it a combination of the generative layer + one or more additional layers?
No additional layers, just whatever is visible.
Would the PNG be saved with the generative fill prompt (layer name) as the file name? Would it be saved with the document name + layer name? What location to save to?
That would be a plus, however I'd just be happy to have them named "document_name+(-Number Sequence)"
Copy link to clipboard
Copied
@boondock – I'll leave this with @c.pfaffenbichler as I am in the middle of other projects and I think that he can do a better job than I can with some of the more advanced AM code required for this task.
Copy link to clipboard
Copied
I am not sure I will be able to look into this sufficiently today, but I should be able to on the weekend.
Hope your projects turn out well!
Copy link to clipboard
Copied
Thanks! I wasn't expecting this level of involvement, so any help you wish to provide I'll gladly accept, regardless of the time it takes. 🙂
Copy link to clipboard
Copied
@c.pfaffenbichler – I unexpectedly finalised both forum projects just now (thanks to some code of yours from 2022). I just needed a break and a fresh perspective as I was stuck!
Copy link to clipboard
Copied
@boondock – To confirm... One layer at a time, with 60 variations in each layer? So if you had 3 layers, then you would have 180 saved images?
Does each layer always have 60 variations, or does this vary?
Does the file contain layer sets?
Or is it just a variable number of generative fill smart object layers?
No special Background layer or other layer kinds?
Copy link to clipboard
Copied
Hey Script Experts,
Apologies for the radio silence. Came down with the flu and haven't quite recovered yet so I've been out of the office for the last two weeks.
To answer your questions:
-Yes, one layer at a time with 60 variations each.
-I guess this one is up to me. I can create 60 variations per layer intentionally if necessary to make the process work easier.
-By layer sets, do you mean layer comps? If so, then no.
-Because I was playing around with this, currently some layers have fewer than 60 (so variable) but I could force to 60 if necessary.
-Nope, no special backgrounds. Just a simple circle png graphic over an alpha channel
I see you've provided three blocks of code below. Was the main one edited to include the improved bits or do I need to copy/paste them where they fit in to the main body?
Thanks again for your attention to this! I'm excited to try it out! 🙂
Copy link to clipboard
Copied
Please try the first Script I posted on this thread as it is.
Copy link to clipboard
Copied
You can try this.
// create png for each variation of generative fill layers;
// 2024, use it at your own risk;
if (app.documents.length > 0) {
var thedoc = activeDocument;
var docName = thedoc.name;
try {
var basename = docName.match(/(.*)\.[^\.]+$/)[1];
var origDocPath = thedoc.fullName;
var docPath = thedoc.path;
}
catch (e) {
var basename = thedoc.name;
var docPath = "~/Desktop"
};
// process layers;
var theSOs = collectSmartObjects ();
for (var m = 0; m < theSOs.length; m++) {
showAllLayers ();
selectLayerByID (theSOs[m][5], false);
hideOthers ();
var theCheck = true;
var theIndex = 0;
while (theCheck == true) {
theCheck = selectGenerativeFillVariation (theIndex);
if (theCheck == true) {savePNG (docPath, basename, theSOs[m][0]+"_"+bufferNumberWithZeros (theIndex+1, 2))};
theIndex++;
}
};
};
////////////////////////////////////
////// select generative fill variation //////
function selectGenerativeFillVariation (theIndex) {
try {
var desc239 = new ActionDescriptor();
var ref6 = new ActionReference();
ref6.putEnumerated( stringIDToTypeID( "layer" ), stringIDToTypeID( "ordinal" ), stringIDToTypeID( "targetEnum" ) );
desc239.putReference( stringIDToTypeID( "null" ), ref6 );
desc239.putInteger( stringIDToTypeID( "index" ), theIndex );
/*var idremainingVariationsCount = stringIDToTypeID( "remainingVariationsCount" );
desc239.putInteger( idremainingVariationsCount, 9 );*/
executeAction( stringIDToTypeID( "selectGeneratedVariation" ), desc239, DialogModes.NO );
return true
} catch (e) {return false}
};
////// hide others //////
function hideOthers () {
var desc2 = new ActionDescriptor();
var list1 = new ActionList();
var ref1 = new ActionReference();
ref1.putEnumerated( charIDToTypeID( "Lyr " ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );
list1.putReference( ref1 );
desc2.putList( charIDToTypeID( "null" ), list1 );
desc2.putBoolean( charIDToTypeID( "TglO" ), true );
executeAction( charIDToTypeID( "Shw " ), desc2, DialogModes.NO );
};
////// buffer number with zeros //////
function bufferNumberWithZeros (number, places) {
var theNumberString = String(number);
for (var o = 0; o < (places - String(number).length); o++) {
theNumberString = String("0" + theNumberString)
};
return theNumberString
};
////// function to png //////
function savePNG (docPath, basename, theSuffix) {
var desc10 = new ActionDescriptor();
var desc11 = new ActionDescriptor();
desc11.putEnumerated( stringIDToTypeID( "method" ), stringIDToTypeID( "PNGMethod" ), stringIDToTypeID( "quick" ) );
desc11.putEnumerated( stringIDToTypeID( "PNGInterlaceType" ), stringIDToTypeID( "PNGInterlaceType" ), stringIDToTypeID( "PNGInterlaceNone" ) );
desc11.putEnumerated( stringIDToTypeID( "PNGFilter" ), stringIDToTypeID( "PNGFilter" ), stringIDToTypeID( "PNGFilterAdaptive" ) );
desc11.putInteger( stringIDToTypeID( "compression" ), 6 );
desc11.putEnumerated( stringIDToTypeID( "embedIccProfileLastState" ), stringIDToTypeID( "embedOff" ), stringIDToTypeID( "embedOff" ) );
var idPNGFormat = stringIDToTypeID( "PNGFormat" );
desc10.putObject( stringIDToTypeID( "as" ), idPNGFormat, desc11 );
desc10.putPath( stringIDToTypeID( "in" ), new File( docPath+"/"+basename+"_"+theSuffix+".png" ) );
desc10.putBoolean( stringIDToTypeID( "copy" ), true );
desc10.putBoolean( stringIDToTypeID( "lowerCase" ), true );
desc10.putBoolean( stringIDToTypeID( "embedProfiles" ), true );
desc10.putEnumerated( stringIDToTypeID( "saveStage" ), stringIDToTypeID( "saveStageType" ), stringIDToTypeID( "saveSucceeded" ) );
executeAction( stringIDToTypeID( "save" ), desc10, DialogModes.NO );
};
////// collect smart objects, probably based on code by paul, mike or x //////
function collectSmartObjects () {
// 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 not layer group collect values;
if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true) {
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
if(layerDesc.hasKey(stringIDToTypeID('smartObject'))) {
var soDesc = layerDesc.getObjectValue(stringIDToTypeID('smartObject'));
var theFileRef = soDesc.getString(stringIDToTypeID('fileReference'));
var theDocID = soDesc.getString(stringIDToTypeID('documentID'));
var isLinked = soDesc.getBoolean(stringIDToTypeID('linked'));
if (isLinked == true) {
var isMissing = soDesc.getBoolean(stringIDToTypeID('linkMissing'));
var isChanged = soDesc.getBoolean(stringIDToTypeID('linkChanged'));
var thePath = soDesc.getPath(stringIDToTypeID('link'));
} else {
var isMissing = undefined;
var isChanged = undefined;
var thePath = undefined
};
/*var x = soDesc.getList(stringIDToTypeID("compsList"));
var theCompsList = soDesc.getObjectValue(stringIDToTypeID("compsList"));
if (theCompsList.count > 2) {
var theCompsList = theCompsList.getList(stringIDToTypeID("compList"));
var theSOComps = new Array;
for (var n = 0; n < theCompsList.count; n++) {
var thisOne = theCompsList.getObjectValue(n);
var compName = thisOne.getString(stringIDToTypeID("name"));
var compID = thisOne.getInteger(stringIDToTypeID("ID"));
var theComment = thisOne.getString(stringIDToTypeID("comment"));
theSOComps.push([compName, compID, theComment]);
};
theLayers.push([theName, theID, theFileRef, theDocID])
theLayers.push([theName, theID, theFileRef, theDocID, theSOComps])
};*/
theLayers.push([theName, isLinked, isMissing, isChanged, thePath, theID, theFileRef, theDocID])
}
}
}
catch (e) {};
};
return theLayers
};
// based on code by mike hale, via paul riggott;
function selectLayerByID(id,add){
add = undefined ? add = false:add
var ref = new ActionReference();
ref.putIdentifier(charIDToTypeID("Lyr "), id);
var desc = new ActionDescriptor();
desc.putReference(charIDToTypeID("null"), ref );
if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) );
desc.putBoolean( charIDToTypeID( "MkVs" ), false );
try{
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
}catch(e){
alert(e.message);
}
};
////// show all layers //////
function showAllLayers () {
// 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"));
var hasBackground = applicationDesc.getBoolean(stringIDToTypeID("hasBackgroundLayer"));
var theStart = 0;
if (hasBackground == false) {theStart++};
// show all layers;
var desc5 = new ActionDescriptor();
var list4 = new ActionList();
var ref4 = new ActionReference();
for (var x = theStart; x <= theNumber; x++) {
ref4.putIndex( charIDToTypeID( "Lyr " ), x );
};
list4.putReference( ref4 );
desc5.putList( charIDToTypeID( "null" ), list4 );
executeAction( charIDToTypeID( "Shw " ), desc5, DialogModes.NO );
};
Copy link to clipboard
Copied
@c.pfaffenbichler – I knew that you would work your magic here, I was spinning my wheels just working out how to increment the selectGeneratedVariation idindex value!
Have you figured out how to identify a generative fill as a special type of a smart object? Previously there were only linked or embedded smart objects, but what if one wishes to differentiate between the 3 types?
Copy link to clipboard
Copied
It seems possible to determine whether a SO is Generative Fill, but in the previous Script I took the lazy route with a try-clause instead.
// 2024, use it at your own risk;
if (app.documents.length > 0) {
alert (isGenerativeFillLayer ())
};
////// check if layer is generative fill //////
function isGenerativeFillLayer () {
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var layerDesc = executeActionGet(ref);
if (layerDesc.hasKey(stringIDToTypeID('smartObject')) == true) {
var soDesc = layerDesc.getObjectValue(stringIDToTypeID('smartObject'));
var soMoreDesc = layerDesc.getObjectValue(stringIDToTypeID('smartObjectMore'));
if (soMoreDesc.hasKey(stringIDToTypeID('generativeDocInfo')) == true) {return true}
else {return false}
} else {return false}
};
Copy link to clipboard
Copied
Thank you!
I have combined your code so that I can check for all 3 kinds!
// Check Test Get Property for Linked Embedded Generative Fill Smart Object Layer.jsx
/* Based on:
https://stackoverflow.com/questions/63010107/get-a-smart-objects-layers-files-directory-source-in-jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/is-there-a-quot-simple-quot-way-to-export-all-generation-variations/m-p/14442568
*/
#target photoshop
if (app.activeDocument.activeLayer.kind == LayerKind.SMARTOBJECT) {
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var layerDesc = executeActionGet(ref);
ref.putProperty(charIDToTypeID("Prpr"), stringIDToTypeID("smartObject"));
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var so = executeActionGet(ref).getObjectValue(stringIDToTypeID("smartObject"));
var soMoreDesc = layerDesc.getObjectValue(stringIDToTypeID('smartObjectMore'));
if (soMoreDesc.hasKey(stringIDToTypeID('generativeDocInfo')) === true) {
alert("Generative Fill Smart Object Layer");
} else if (so.getBoolean(stringIDToTypeID("linked")) === true) {
alert("Linked Smart Object Layer");
} else {
alert("Embedded Smart Object Layer");
}
} else {
alert("The layer isn't a Smart Object");
}
Copy link to clipboard
Copied
I did not find a way yet to identify the selected Variation.
That might become of interest at some point.
Copy link to clipboard
Copied
I figured out a different way to do this, so I thought that I would belatedly post it:
/*
Generative Layer Variations to PNG.jsx
v1.0 - 23rd April 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/is-there-a-quot-simple-quot-way-to-export-all-generation-variations/m-p/14442568
*/
#target photoshop
if (app.activeDocument.activeLayer.kind == LayerKind.SMARTOBJECT) {
// If the active layer is a smart object generative fill layer
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var layerDesc = executeActionGet(ref);
ref.putProperty(charIDToTypeID("Prpr"), stringIDToTypeID("smartObject"));
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var so = executeActionGet(ref).getObjectValue(stringIDToTypeID("smartObject"));
var soMoreDesc = layerDesc.getObjectValue(stringIDToTypeID('smartObjectMore'));
if (soMoreDesc.hasKey(stringIDToTypeID('generativeDocInfo')) === true) {
// Document save path and name variables
var docPath = app.activeDocument.path.fsName;
var docName = app.activeDocument.name.replace(/\.[^\.]+$/, '');
// Dupe the layer
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
var reference2 = new ActionReference();
reference.putClass(s2t("document"));
descriptor.putReference(s2t("null"), reference);
descriptor.putString(s2t("name"), app.activeDocument.name.replace(/\.[^\.]+$/, ''));
reference2.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
descriptor.putReference(s2t("using"), reference2);
descriptor.putString(s2t("layerName"), app.activeDocument.activeLayer.name);
executeAction(s2t("make"), descriptor, DialogModes.NO);
// Convert the SO to layers
var idplacedLayerConvertToLayers = stringIDToTypeID("placedLayerConvertToLayers");
executeAction(idplacedLayerConvertToLayers, undefined, DialogModes.NO);
// Ungroup the layers x2
for (u = 0; u < 2; u++)
{
ungroupLayers();
}
// Setup the layer name
var zeroPadLength = 3;
var startNumber = 1;
var generativeName = app.activeDocument.layers[0].name;
// Forward loop and rename the layers from the top down
for (var i = 0; i < activeDocument.layers.length; i++) {
activeDocument.layers[i].name = generativeName + " " + zeroPad(startNumber, zeroPadLength);
startNumber++
}
app.refresh();
// Get all the root/top-level layers in the document
var layers = app.activeDocument.layers;
// Set the layer processing counter
var counter = 0;
// Loop through the layers
for (var j = 0; j < layers.length; j++) {
// Hide all layers
for (var k = 0; k < layers.length; k++) {
layers[k].visible = false;
}
// Make the current layer visible
layers[j].visible = true;
// PNG export
exportPNG();
// Increment the layer processing counter for each layer in the loop
counter++
}
// Close the temp doc
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
alert(counter + " files saved to " + '"' + docPath + '"');
} else {
alert("The Layer isn't a Generative Smart Object!");
}
} else {
alert("The Layer isn't a Generative Smart Object!");
}
///// FUNCTIONS /////
function exportPNG() {
var pngOptions = new ExportOptionsSaveForWeb();
pngOptions.PNG8 = false;
pngOptions.transparency = true;
pngOptions.interlaced = false;
pngOptions.quality = 100;
pngOptions.includeProfile = true;
pngOptions.format = SaveDocumentType.PNG;
app.activeDocument.exportDocument(File(docPath + "/" + docName + " " + layers[j].name + ".png"), ExportType.SAVEFORWEB, pngOptions);
}
function ungroupLayers() {
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
descriptor.putReference(s2t("null"), reference);
executeAction(s2t("ungroupLayersEvent"), descriptor, DialogModes.NO);
}
function zeroPad(num, digit) {
var tmp = num.toString();
while (tmp.length < digit) {
tmp = "0" + tmp;
}
return tmp;
}
Edit: Here it is for all layers, not just the active layer -
/*
All Generative Layer Variations to PNG.jsx
v1.0 - 19th July 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/is-there-a-quot-simple-quot-way-to-export-all-generation-variations/m-p/14442568
*/
if (!documents.length) {
alert('There are no documents open!');
} else {
activeDocument.suspendHistory('All Generative Layer Variations to PNG.jsx', 'main()');
}
function main() {
// Set the layer processing counter
var counter = 0;
// Document save path and name variables
var docPath = app.activeDocument.path.fsName;
var docName = app.activeDocument.name.replace(/\.[^\.]+$/, '');
// Script running notification window - courtesy of William Campbell
/* https://www.marspremedia.com/download?asset=adobe-script-tutorial-11.zip
https://youtu.be/JXPeLi6uPv4?si=Qx0OVNLAOzDrYPB4 */
var working;
working = new Window("palette");
working.preferredSize = [300, 80];
working.add("statictext");
working.t = working.add("statictext");
working.add("statictext");
working.display = function (message) {
this.t.text = message || "Script running, please wait...";
this.show();
app.refresh();
};
working.display();
// Call the file processing function
processAllLayersAndSets(app.activeDocument);
// Ensure Photoshop has focus before closing the running script notification window
app.bringToFront();
working.close();
// End of script notification
app.beep();
alert(counter + " files saved to " + '"' + docPath + '"');
function processAllLayersAndSets(obj) {
// Process Layers
for (var i = obj.artLayers.length - 1; 0 <= i; i--) {
app.activeDocument.activeLayer = obj.artLayers[i];
// Start main code to apply to the layers here
saveGenerativeVariations();
// Finish main code to apply to the layers here
}
// Process Layer Set Layers
for (var i = obj.layerSets.length - 1; 0 <= i; i--) {
processAllLayersAndSets(obj.layerSets[i]);
}
}
function saveGenerativeVariations() {
if (app.activeDocument.activeLayer.kind == LayerKind.SMARTOBJECT) {
// If the active layer is a smart object generative fill layer
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var layerDesc = executeActionGet(ref);
ref.putProperty(charIDToTypeID("Prpr"), stringIDToTypeID("smartObject"));
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var so = executeActionGet(ref).getObjectValue(stringIDToTypeID("smartObject"));
var soMoreDesc = layerDesc.getObjectValue(stringIDToTypeID('smartObjectMore'));
if (soMoreDesc.hasKey(stringIDToTypeID('generativeDocInfo')) === true) {
// Dupe the layer
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
var reference2 = new ActionReference();
reference.putClass(s2t("document"));
descriptor.putReference(s2t("null"), reference);
descriptor.putString(s2t("name"), app.activeDocument.name.replace(/\.[^\.]+$/, ''));
reference2.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
descriptor.putReference(s2t("using"), reference2);
descriptor.putString(s2t("layerName"), app.activeDocument.activeLayer.name);
executeAction(s2t("make"), descriptor, DialogModes.NO);
// Convert the SO to layers
var idplacedLayerConvertToLayers = stringIDToTypeID("placedLayerConvertToLayers");
executeAction(idplacedLayerConvertToLayers, undefined, DialogModes.NO);
// Ungroup the layers x2
for (u = 0; u < 2; u++) {
ungroupLayers();
}
// Setup the layer name
var zeroPadLength = 3;
var startNumber = 1;
var generativeName = app.activeDocument.layers[0].name;
// Forward loop and rename the layers from the top down
for (var i = 0; i < activeDocument.layers.length; i++) {
activeDocument.layers[i].name = generativeName + " " + zeroPad(startNumber, zeroPadLength);
startNumber++
}
app.refresh();
// Get all the root/top-level layers in the document
var layers = app.activeDocument.layers;
// Loop through the layers
for (var j = 0; j < layers.length; j++) {
// Hide all layers
for (var k = 0; k < layers.length; k++) {
layers[k].visible = false;
}
// Make the current layer visible
layers[j].visible = true;
// TIFF save
//var saveFileTIFF = new File(docPath + "/" + docName + " " + layers[j].name + ".tif");
//saveTIFF(saveFileTIFF, true);
// PNG export
exportPNG();
// Increment the layer processing counter for each layer in the loop
counter++
}
// Close the temp doc
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
} else {
//alert("The Layer isn't a Generative Smart Object!");
}
} else {
//alert("The Layer isn't a Generative Smart Object!");
}
///// FUNCTIONS /////
function exportPNG() {
var pngOptions = new ExportOptionsSaveForWeb();
pngOptions.PNG8 = false;
pngOptions.transparency = true;
pngOptions.interlaced = false;
pngOptions.quality = 100;
pngOptions.includeProfile = true;
pngOptions.format = SaveDocumentType.PNG;
app.activeDocument.exportDocument(File(docPath + "/" + docName + " " + layers[j].name + ".png"), ExportType.SAVEFORWEB, pngOptions);
}
function saveTIFF(saveFileTIFF, aCopy) {
tiffSaveOptions = new TiffSaveOptions();
tiffSaveOptions.embedColorProfile = true;
// ByteOrder.MACOS or ByteOrder.IBM
tiffSaveOptions.byteOrder = ByteOrder.IBM;
tiffSaveOptions.transparency = true;
tiffSaveOptions.layers = true;
tiffSaveOptions.layerCompression = LayerCompression.ZIP;
tiffSaveOptions.interleaveChannels = true;
tiffSaveOptions.alphaChannels = true;
tiffSaveOptions.annotations = true;
tiffSaveOptions.spotColors = true;
tiffSaveOptions.saveImagePyramid = false;
// NONE | JPEG | TIFFLZW | TIFFZIP
tiffSaveOptions.imageCompression = TIFFEncoding.TIFFLZW;
activeDocument.saveAs(saveFileTIFF, tiffSaveOptions, aCopy, Extension.LOWERCASE);
}
function ungroupLayers() {
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
descriptor.putReference(s2t("null"), reference);
executeAction(s2t("ungroupLayersEvent"), descriptor, DialogModes.NO);
}
function zeroPad(num, digit) {
var tmp = num.toString();
while (tmp.length < digit) {
tmp = "0" + tmp;
}
return tmp;
}
}
}