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

How to: auto stack smart objects into single file

Explorer ,
Jan 02, 2020 Jan 02, 2020

Hi Photoshop community,

 

I have a series of images open as smart objects and want them together in 1 layered file. Aside from manually dragging and dropping them into one file, is there a way to automatically do this?

 

I used to do this all the time with flat images via scripts > image processor, but for some reason I cannot use this to do the same with Smart objects.

 

Any insight would be greatly appreicated! 

866
Translate
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
Adobe
Community Expert ,
Jan 02, 2020 Jan 02, 2020

You can use Layer > Duplicate Layer to dupe a copy of Doc A to Doc B, retaining the smart object from Doc A.

 

An action can fully automate the task if you always have the same number of files to combine. An action could semi-automate some of the manual steps of this task if the open document count varies... however, a script would be ideal.

Translate
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
People's Champ ,
Jan 02, 2020 Jan 02, 2020
Maybe it suits you?
Menu-> File-> Scripts-> Load Files into Stack
 
Translate
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 ,
Jan 02, 2020 Jan 02, 2020

That was my first thought r-bin – however it does not work with open files that contain a single SO layer, which is what I understand the OP is dealing with:

 

so-error.png

 

I just tried with no open files, and they were all silently skipped.

Translate
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 ,
Jan 02, 2020 Jan 02, 2020

The following script is not that clean/pretty, but it does work.

 

Open all single layer smart object files that you wish to stack, then run this script. It is assumed that all files are the same pixel dimensions, colour mode/space and resolution.

 

The result will be a single open image, with each separate input image being a smart object layer. Layer names and sort order leave something to be desired...

 

 

 

var baseDoc = app.activeDocument;
baseDoc.duplicate('SO Stack');
var soStack = app.activeDocument;
baseDoc.close();

// Duplicate single SO layer to soStack doc
for (var i = 0; i < app.documents.length; i++) {
    app.activeDocument = app.documents[i];
    displayDialogs = DialogModes.NO;
    app.activeDocument.layers[0].duplicate(soStack);
};

// Remove the extra layer (yes this is hack to work around the poor coding :)
app.activeDocument.layers[0].remove();

// Close all open files that are not named 'SO Stack'
var docs = app.documents;
for(var i = docs.length - 1; i >= 0; i--){
   if(docs[i].name.indexOf('SO Stack') < 0){
      docs[i].close();
   }
}

 

 

 

https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html

Translate
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 ,
Jan 03, 2020 Jan 03, 2020
LATEST

Here is a slightly refined version of the original script, this version will name the SO Stack layers after the original document to aid in layer identification:

 

 

var baseDoc = app.activeDocument;
var baseName = app.activeDocument.name.replace(/\.[^\.]+$/, ''); // Base Doc Name RegEx
app.activeDocument.activeLayer.name = baseName;
baseDoc.duplicate('SO Stack');
baseDoc.close(SaveOptions.DONOTSAVECHANGES);

// Duplicate single SO layer to SO Stack doc
for (var i = 0; i < app.documents.length; i++) {
    app.activeDocument = app.documents[i];
    displayDialogs = DialogModes.NO;

    var docName = app.activeDocument.name.replace(/\.[^\.]+$/, ''); // Source Doc Name RegEx
    duplicate(docName, 5); // Source Doc for Duplicate Layer Rename
    function duplicate(name2, version) {
        var c2t = function (s) {
            return app.charIDToTypeID(s);
        };
    
        var s2t = function (s) {
            return app.stringIDToTypeID(s);
        };
    
        var descriptor = new ActionDescriptor();
        var list = new ActionList();
        var reference = new ActionReference();
        var reference2 = new ActionReference();
    
        reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
        descriptor.putReference(c2t("null"), reference);
        reference2.putName(s2t("document"), "SO Stack"); // Target Doc for Duplicate Layer
        descriptor.putReference(s2t("to"), reference2);
        descriptor.putString(s2t("name"), name2);
        descriptor.putInteger(s2t("version"), version);
        list.putInteger(3);
        descriptor.putList(s2t("ID"), list);
        executeAction(s2t("duplicate"), descriptor, DialogModes.NO);
    }

};

// Remove the extra layer (yes this is hack to work around the poor coding :)
app.activeDocument.layers[0].remove();

// Close all open files that are not named 'SO Stack'
var docs = app.documents;
for (var i = docs.length - 1; i >= 0; i--) {
    if (docs[i].name.indexOf('SO Stack') < 0) {
        docs[i].close();
    }
}

 

 

P.S. You could graft this code onto the end of the script to alphabetically sort the layers:

 

https://gist.github.com/vladocar/1628874

 

var layers = activeDocument.layers;
	var layersArray = [];
	var len = layers.length;
	


	// store all layers in an array
	for (var i = 0; i < len; i++) {
		layersArray.push(layers[i]);
	}

	// sort layer top to bottom
	layersArray.sort();

	for (i = 0; i < len; i++) {
		layersArray[i].move(layers[i], ElementPlacement.PLACEBEFORE);
    }
Translate
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