Skip to main content
Known Participant
June 24, 2022
Question

Photoshop Script for opening template action and adding selected files into folder

  • June 24, 2022
  • 2 replies
  • 2447 views

Can someone help me with this photoshop script

 

I have created an action to automatically create an document with 3 artboards:

app.doAction("Create Document","APP IMAGES")
 
I want to be able to select a group of images in finder, and the run the script to create the template document above and place linked images into 3 separate artboards (already in the template):
 
The artboards are called (and will never change):
SQ 2400x2400
VT 1800x2474
VT 2400x3000
 
I then have 3 separate scripts (below) to rename the filenames by group:
 
for (var i = 0 ; i < app.activeDocument.activeLayer.layers.length ; i++)
{
var LAYER = app.activeDocument.activeLayer.layers[i];
var VISIBLE = LAYER.visible;
// replace ' ' with ' '
//Script takes entire variable name and adds prefix and suffix
LAYER.name = LAYER.name.replace(/\.[^\.]+$/, '');
var newLayerName = "2400x2400 SQ 2400x2400/" + LAYER.name + ".png";

LAYER.name = newLayerName;
LAYER.visible = VISIBLE
}
 
for (var i = 0 ; i < app.activeDocument.activeLayer.layers.length ; i++)
{
var LAYER = app.activeDocument.activeLayer.layers[i];
var VISIBLE = LAYER.visible;
// replace ' ' with ' '
//Script takes entire variable name and adds prefix and suffix
LAYER.name = LAYER.name.replace(/\.[^\.]+$/, '');
var newLayerName = "1800x2474 VT 1800x2474/" + LAYER.name + ".png";

LAYER.name = newLayerName;
LAYER.visible = VISIBLE
}
 
for (var i = 0 ; i < app.activeDocument.activeLayer.layers.length ; i++)
{
var LAYER = app.activeDocument.activeLayer.layers[i];
var VISIBLE = LAYER.visible;
// replace ' ' with ' '
//Script takes entire variable name and adds prefix and suffix
LAYER.name = LAYER.name.replace(/\.[^\.]+$/, '');
var newLayerName = "2400x3000 VT 2400x3000/" + LAYER.name + ".png";

LAYER.name = newLayerName;
LAYER.visible = VISIBLE
}
 
 
Then, marketing can move around the images to their liking.
And I can just generate > assets neatly into correct groups, correct names and extenstions, and deliver it back to them immediately. This process will be used every time we have new images. It is not a one off.
 
It works, but I have a bunch of actions I have to click to execute it.
I am looking to combine it all together in one script. Anyone know how to do this?
This topic has been closed for replies.

2 replies

Stephen Marsh
Community Expert
June 25, 2022

Here is a start... Run your action to create the doc with the 3 appropriately named/sized artboards and then run this script. You can of course add your code to call the action. If you don't wish to rely on the action, then you would need to code the creation of the new doc and artboards and add this to the script. This version places the selected files three times. I believe that it would be more efficient to simply dupe the placed layers from the first artboard to the other two, however, this is a start.

Edit: Original code updated with a 1.1 version to centre content

 

    /*
    Selected Files Place Linked to Named Artboards v1.jsx
    v1.1, 26th June 2022, Stephen Marsh
    https://community.adobe.com/t5/photoshop-ecosystem-discussions/photoshop-script-for-opening-template-action-and-adding-selected-files-into-folder/td-p/13028265
    Note: An open doc with the three correctly named target artboards is required
    */

    (function () {

        if (app.documents.length > 0) {

            var savedDisplayDialogs = app.displayDialogs;
            app.displayDialogs = DialogModes.NO;
            var origUnits = app.preferences.rulerUnits;
            app.preferences.rulerUnits = Units.PIXELS;

            var selectFiles = File.openDialog("Please select the file or files:", Multiselect = true);
            if (selectFiles === null) {
                //alert("Script cancelled!");
                return;
            }
            selectFiles.sort();
            //selectFiles.sort().reverse();

            try {

                // Select the SQ 2400x2400 artboard
                activeDocument.activeLayer = activeDocument.layerSets.getByName('SQ 2400x2400');
                for (var i = 0; i < selectFiles.length; i++) {
                    placeFile(new File(selectFiles[i]), true, 0, 0);
                    // Reset SO transform
                    //var idplacedLayerResetTransforms = stringIDToTypeID("placedLayerResetTransforms");
                    //executeAction(idplacedLayerResetTransforms, undefined, DialogModes.NO);
                }
                activeDocument.activeLayer = activeDocument.layerSets.getByName('SQ 2400x2400');
                if (app.activeDocument.activeLayer.typename == 'LayerSet') {
                    selectActiveSetContents();
                }
                align2SelectAll('AdCH');
                align2SelectAll('AdCV');

                // Select the VT 1800x2474 artboard
                activeDocument.activeLayer = activeDocument.layerSets.getByName('VT 1800x2474');
                for (var i = 0; i < selectFiles.length; i++) {
                    placeFile(new File(selectFiles[i]), true, 0, 0);
                    // Reset SO transform
                    //var idplacedLayerResetTransforms = stringIDToTypeID("placedLayerResetTransforms");
                    //executeAction(idplacedLayerResetTransforms, undefined, DialogModes.NO);
                }
                activeDocument.activeLayer = activeDocument.layerSets.getByName('VT 1800x2474');
                if (app.activeDocument.activeLayer.typename == 'LayerSet') {
                    selectActiveSetContents();
                }
                align2SelectAll('AdCH');
                align2SelectAll('AdCV');

                // Select the VT 2400x3000 artboard
                activeDocument.activeLayer = activeDocument.layerSets.getByName('VT 2400x3000');
                for (var i = 0; i < selectFiles.length; i++) {
                    placeFile(new File(selectFiles[i]), true, 0, 0);
                    // Reset SO transform
                    //var idplacedLayerResetTransforms = stringIDToTypeID("placedLayerResetTransforms");
                    //executeAction(idplacedLayerResetTransforms, undefined, DialogModes.NO);
                }
                activeDocument.activeLayer = activeDocument.layerSets.getByName('VT 2400x3000');
                if (app.activeDocument.activeLayer.typename == 'LayerSet') {
                    selectActiveSetContents();
                }
                align2SelectAll('AdCH');
                align2SelectAll('AdCV');

                // End of script
                app.beep();
                app.displayDialogs = savedDisplayDialogs;
                app.preferences.rulerUnits = origUnits;

            } catch (error) {
                alert("An unexpected error occurred!");
            }


            // Functions

            function placeFile(null2, linked, horizontal, vertical) {
                var s2t = function (s) {
                    return app.stringIDToTypeID(s);
                };
                var AD = new ActionDescriptor();
                AD.putInteger(s2t("ID"), 1);
                AD.putPath(s2t("null"), null2);
                AD.putBoolean(s2t("linked"), linked); // false for embedded
                AD.putEnumerated(s2t("freeTransformCenterState"), s2t("quadCenterState"), s2t("QCSAverage"));
                AD.putUnitDouble(s2t("horizontal"), s2t("pixelsUnit"), horizontal);
                AD.putUnitDouble(s2t("vertical"), s2t("pixelsUnit"), vertical);
                AD.putObject(s2t("offset"), s2t("offset"), AD);
                executeAction(s2t("placeEvent"), AD, DialogModes.NO);
            }

            function selectActiveSetContents() {
                /* https://gist.github.com/joonaspaakko/1add5c6a905216740c9c922a657636e1 */
                var doc = app.activeDocument;
                var sourceGroup = app.activeDocument.activeLayer;

                // Make a temp group with a temp layer inside it:
                // [Parent group]
                // - [TEMP GROUP]
                // - - [TEMP LAYER]

                var tempGroup = sourceGroup.layerSets.add();
                tempGroup.name = 'TEMP GROUP';
                var tempLayer = tempGroup.artLayers.add();
                tempLayer.name = 'TEMP LAYER';
                // Loop through all direct child element and move the last layer below 'TEMP LAYER'
                var children_length = sourceGroup.layers.length - 1;
                for (var i = 0; i < children_length; i++) {
                    var lastLayer = sourceGroup.layers[sourceGroup.layers.length - 1];
                    lastLayer.move(tempGroup.layers[0], ElementPlacement.PLACEAFTER);
                }
                // Get rid of TEMP LAYER
                tempLayer.remove();
                // Get rid of TEMP GROUP by ungrouping it, which also happens to select its children.
                doc.activeLayer = tempGroup;
                // Ungroup tempGroup
                var idungroupLayersEvent = stringIDToTypeID("ungroupLayersEvent");
                var desc702 = new ActionDescriptor();
                var idnull = charIDToTypeID("null");
                var ref427 = new ActionReference();
                var idLyr = charIDToTypeID("Lyr ");
                var idOrdn = charIDToTypeID("Ordn");
                var idTrgt = charIDToTypeID("Trgt");
                ref427.putEnumerated(idLyr, idOrdn, idTrgt);
                desc702.putReference(idnull, ref427);
                executeAction(idungroupLayersEvent, desc702, DialogModes.NO);
            }

            function align2SelectAll(method) {
                /* https://gist.github.com/MarshySwamp/df372e342ac87854ffe08e79cbdbcbb5 */
                app.activeDocument.selection.selectAll();
                var desc = new ActionDescriptor();
                var ref = new ActionReference();
                ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
                desc.putReference(charIDToTypeID("null"), ref);
                desc.putEnumerated(charIDToTypeID("Usng"), charIDToTypeID("ADSt"), charIDToTypeID(method));
                try {
                    executeAction(charIDToTypeID("Algn"), desc, DialogModes.NO);
                } catch (e) {}
                app.activeDocument.selection.deselect();
            }

        } else {
            alert('A document must be open to use this script!');
        }

    })();

 

 

I appreciate that you wish to combine other code, I'd just start simply by getting the separate components to work. Then you can combine the separate scripts by either calling them from an action/helper script before putting in more work in combining the code to a single script.

 

 

Edit: Here is an alternate "B" version of the original script. Rather than placing the images 3 times, this version places them once and then offers an interactive layer duplication so that you can manually target the remaining artboards. Due to what appears to be a bug, the recorded destination artboard is being ignored. I have not tested with large quantities of images, so in theory, this should be faster than placing three separate times.

 

/*
Selected Files Place Linked to Named Artboards v1.jsx
v1.0B, 26th June 2022, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/photoshop-script-for-opening-template-action-and-adding-selected-files-into-folder/td-p/13028265
Note: An open doc with the three correctly named target artboards is required
      This "B" version of the original script uses an interactive duplicate layer, rather than placing the files 3 separate times
      Due to a BUG? the target artboard recorded via the ScriptingListener plugin is ignored, requiring the interactive workaround
*/

(function () {

    if (app.documents.length > 0) {

        var savedDisplayDialogs = app.displayDialogs;
        app.displayDialogs = DialogModes.NO;
        var origUnits = app.preferences.rulerUnits;
        app.preferences.rulerUnits = Units.PIXELS;

        var selectFiles = File.openDialog("Please select the file or files:", Multiselect = true);
        if (selectFiles === null) {
            //alert("Script cancelled!");
            return;
        }
        selectFiles.sort();
        //selectFiles.sort().reverse();

        try {

            // Select the SQ 2400x2400 artboard
            activeDocument.activeLayer = activeDocument.layerSets.getByName('SQ 2400x2400');
            for (var i = 0; i < selectFiles.length; i++) {
                placeFile(new File(selectFiles[i]), true, 0, 0);
                // Reset SO transform
                //var idplacedLayerResetTransforms = stringIDToTypeID("placedLayerResetTransforms");
                //executeAction(idplacedLayerResetTransforms, undefined, DialogModes.NO);
            }
            activeDocument.activeLayer = activeDocument.layerSets.getByName('SQ 2400x2400');
            if (app.activeDocument.activeLayer.typename == 'LayerSet') {
                selectActiveSetContents();
            }
            align2SelectAll('AdCH');
            align2SelectAll('AdCV');

            // Manually dupe the layers to the other artboards
            interactiveDupeLayers();
            align2SelectAll('AdCH');
            align2SelectAll('AdCV');
            
            interactiveDupeLayers();
            align2SelectAll('AdCH');
            align2SelectAll('AdCV');
            
            // End of script
            app.beep();
            app.displayDialogs = savedDisplayDialogs;
            app.preferences.rulerUnits = origUnits;

        } catch (error) {
            alert("An unexpected error occurred!");
        }


        // Functions

        function placeFile(null2, linked, horizontal, vertical) {
            var s2t = function (s) {
                return app.stringIDToTypeID(s);
            };
            var AD = new ActionDescriptor();
            AD.putInteger(s2t("ID"), 1);
            AD.putPath(s2t("null"), null2);
            AD.putBoolean(s2t("linked"), linked); // false for embedded
            AD.putEnumerated(s2t("freeTransformCenterState"), s2t("quadCenterState"), s2t("QCSAverage"));
            AD.putUnitDouble(s2t("horizontal"), s2t("pixelsUnit"), horizontal);
            AD.putUnitDouble(s2t("vertical"), s2t("pixelsUnit"), vertical);
            AD.putObject(s2t("offset"), s2t("offset"), AD);
            executeAction(s2t("placeEvent"), AD, DialogModes.NO);
        }

        function selectActiveSetContents() {
            /* https://gist.github.com/joonaspaakko/1add5c6a905216740c9c922a657636e1 */
            var doc = app.activeDocument;
            var sourceGroup = app.activeDocument.activeLayer;

            // Make a temp group with a temp layer inside it:
            // [Parent group]
            // - [TEMP GROUP]
            // - - [TEMP LAYER]

            var tempGroup = sourceGroup.layerSets.add();
            tempGroup.name = 'TEMP GROUP';
            var tempLayer = tempGroup.artLayers.add();
            tempLayer.name = 'TEMP LAYER';
            // Loop through all direct child element and move the last layer below 'TEMP LAYER'
            var children_length = sourceGroup.layers.length - 1;
            for (var i = 0; i < children_length; i++) {
                var lastLayer = sourceGroup.layers[sourceGroup.layers.length - 1];
                lastLayer.move(tempGroup.layers[0], ElementPlacement.PLACEAFTER);
            }
            // Get rid of TEMP LAYER
            tempLayer.remove();
            // Get rid of TEMP GROUP by ungrouping it, which also happens to select its children.
            doc.activeLayer = tempGroup;
            // Ungroup tempGroup
            var idungroupLayersEvent = stringIDToTypeID("ungroupLayersEvent");
            var desc702 = new ActionDescriptor();
            var idnull = charIDToTypeID("null");
            var ref427 = new ActionReference();
            var idLyr = charIDToTypeID("Lyr ");
            var idOrdn = charIDToTypeID("Ordn");
            var idTrgt = charIDToTypeID("Trgt");
            ref427.putEnumerated(idLyr, idOrdn, idTrgt);
            desc702.putReference(idnull, ref427);
            executeAction(idungroupLayersEvent, desc702, DialogModes.NO);
        }

        function interactiveDupeLayers() {
            // Interactive layer dupe
            var idduplicate = stringIDToTypeID("duplicate");
            var desc2608 = new ActionDescriptor();
            var idnull = stringIDToTypeID("null");
            var ref965 = new ActionReference();
            var idlayer = stringIDToTypeID("layer");
            var idordinal = stringIDToTypeID("ordinal");
            var idtargetEnum = stringIDToTypeID("targetEnum");
            ref965.putEnumerated(idlayer, idordinal, idtargetEnum);
            desc2608.putReference(idnull, ref965);
            executeAction(idduplicate, desc2608, DialogModes.ALL);
        }

        function align2SelectAll(method) {
            /* https://gist.github.com/MarshySwamp/df372e342ac87854ffe08e79cbdbcbb5 */
            app.activeDocument.selection.selectAll();
            var desc = new ActionDescriptor();
            var ref = new ActionReference();
            ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
            desc.putReference(charIDToTypeID("null"), ref);
            desc.putEnumerated(charIDToTypeID("Usng"), charIDToTypeID("ADSt"), charIDToTypeID(method));
            try {
                executeAction(charIDToTypeID("Algn"), desc, DialogModes.NO);
            } catch (e) {}
            app.activeDocument.selection.deselect();
        }

    } else {
        alert('A document must be open to use this script!');
    }

})();

 

Known Participant
June 25, 2022

   

Gotcha, This worked!

 

The only thing I would change with this part is so that the images load centered on the artboards (I realize I said that didn’t matter before =/), so it's just a matter of holding down option and expanding them (unless there is a way to expand to fill?), and it just becomes about adjusting for the photographer’s eye.

 

Also I noticed that generate assets didn’t work unless I did tinker with each image. Is there some sort of “auto place” for it to recognize the image off the bat?

 

I can see someone liking one image the way it is and going on to the next one, only for that one not to show up because they didn’t transform it.

 

Any thoughts and suggestions? I really appreciate you helping me with this!!

Stephen Marsh
Community Expert
July 13, 2022

Do you know how to achieve this?



@Anne24506383rxky wrote:

Do you know how to achieve this?


 

It is in the updated code above for version 1.1 above, it uses the same code to centre the images on the artboards as the B version and should provide the same final result. I have tested it again just now and it works as expected with my test artboard and image files.

Stephen Marsh
Community Expert
June 25, 2022

Starting at this point:

 


@Anne24506383rxky wrote:
I want to be able to select a group of images in finder, and the run the script to create the template document above and place linked images into 3 separate artboards (already in the template):
 
The artboards are called (and will never change):
SQ 2400x2400
VT 1800x2474
VT 2400x3000

 

How are the files named and sized in relation to the artboard's names and or sizes?

 

How would the script know which order to place the images into each artboard?

 

Known Participant
June 25, 2022
So for example, if there are 100 images. Then the script would select art board SQ 2400x2400 and place the 100 linked images in that artboard, then select art board VT 1800x2474 and place the same 100 linked images, and then select artboard VT 2400x3000, and place the same 100 linked images. They are duplicates. I’m not sure if there is a script to do that.

Right now I just have an action that duplicates the selected images into the other two folders. The sizes of the images don’t matter, they are close to the artboard size anyway. The marketing team would adjust and play with size and positioning each photo with the artboard anyway. I just need them duplicated under the 3 artboards in the layers window.


Get Outlook for iOS<>
Known Participant
June 25, 2022

The order of the images do not matter.