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;
}
}
}