• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
7

Is there a "simple" way to export all generation variations?

Explorer ,
Feb 23, 2024 Feb 23, 2024

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?

TOPICS
Actions and scripting , Windows

Views

1.5K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 2 Correct answers

Community Expert , Feb 23, 2024 Feb 23, 2024

You can try this. 

Screenshot 2024-02-23 at 13.05.41.pngScreenshot 2024-02-23 at 13.10.25.png

// 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
...

Votes

Translate

Translate
Community Expert , Apr 23, 2024 Apr 23, 2024

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
...

Votes

Translate

Translate
Adobe
Community Expert ,
Feb 23, 2024 Feb 23, 2024

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. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 23, 2024 Feb 23, 2024

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. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 23, 2024 Feb 23, 2024

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). 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 23, 2024 Feb 23, 2024

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 23, 2024 Feb 23, 2024

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?

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 23, 2024 Feb 23, 2024

Copy link to clipboard

Copied

quoteIt 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)"

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 23, 2024 Feb 23, 2024

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 23, 2024 Feb 23, 2024

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! 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 23, 2024 Feb 23, 2024

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. 🙂

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 23, 2024 Feb 23, 2024

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!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 23, 2024 Feb 23, 2024

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?

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Mar 07, 2024 Mar 07, 2024

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! 🙂

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 07, 2024 Mar 07, 2024

Copy link to clipboard

Copied

Please try the first Script I posted on this thread as it is. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 23, 2024 Feb 23, 2024

Copy link to clipboard

Copied

You can try this. 

Screenshot 2024-02-23 at 13.05.41.pngScreenshot 2024-02-23 at 13.10.25.png

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 23, 2024 Feb 23, 2024

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?

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 23, 2024 Feb 23, 2024

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 23, 2024 Feb 23, 2024

Copy link to clipboard

Copied

@c.pfaffenbichler 

 

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

 

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 24, 2024 Feb 24, 2024

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. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 23, 2024 Apr 23, 2024

Copy link to clipboard

Copied

LATEST

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

}

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines