Photoshop Script for opening template action and adding selected files into folder
Copy link to clipboard
Copied
Can someone help me with this photoshop script
I have created an action to automatically create an document with 3 artboards:
LAYER.name = newLayerName;
LAYER.visible = VISIBLE
LAYER.name = newLayerName;
LAYER.visible = VISIBLE
LAYER.name = newLayerName;
LAYER.visible = VISIBLE
Explore related tutorials & articles
Copy link to clipboard
Copied
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 2400x2400VT 1800x2474VT 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?
Copy link to clipboard
Copied
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<>
Copy link to clipboard
Copied
The order of the images do not matter.
Copy link to clipboard
Copied
@Anne24506383rxky – thanks that helps, I think we are getting somewhere...
Wouldn't it be more efficient to have a single artboard and place the 100 or variable amount of images into the artboard, then simply dupe and rename it to create the other two duplicate artboards?
Edit: Will the files already be in a user-selected folder, or will you have to manually select multiple files while deciding not to select other files? Ideally one just selects a folder, but that only works if the target folder only contains the files you wish to place. Files could be excluded based on extension/type or naming pattern etc.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
@Anne24506383rxky – When it comes to automation, IMHO, nothing to do with artboards is easy, they overly complicate things.
Can you share the action that creates the new doc/artboards as you need them created?
I thought that I could skip this first step, however, I am getting the impression that any assumptions that I make will paint me into a corner that will take more work to get out of than simply starting at the same point that you are.
Copy link to clipboard
Copied
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!');
}
})();
Copy link to clipboard
Copied
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!!
Copy link to clipboard
Copied
I labeled those photos wrong. The first one is Created Document action, Ran Your Duplicate Script, Then the Rename Script. The second one is just after transforming the photo. And the third is what the assets look like.
Copy link to clipboard
Copied
@Anne24506383rxky – I have updated the original script to a v1.1 version and also added a v1.0 "B" version for consideration that duplicates the layers rather than placing them another two times.
Let me know how this goes...
Copy link to clipboard
Copied
Anne24506383rxky wrote:
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?
Adobe Generator has always been a little "inconsistent"... to put things kindly.
You will notice that I commented out a block of code in each of the three loops for placing the images as linked smart objects:
// Reset SO transform
//var idplacedLayerResetTransforms = stringIDToTypeID("placedLayerResetTransforms");
//executeAction(idplacedLayerResetTransforms, undefined, DialogModes.NO);
Simply remove the comment // slashes from the 2nd and 3rd lines and the placed smart object will have its initial transformations reset. I left this in as a placeholder just in case it was required...
I don't know if this is enough to register as a change or not?
Otherwise, it would be simple enough to add a bit of code to reduce the smart object to 99% scale or to move it 1px or something else to hopefully register as a change.
Copy link to clipboard
Copied
Anne24506383rxky wrote:
...so it's just a matter of holding down option and expanding them (unless there is a way to expand to fill?)...
Do you mean that the size of the placed images doesn't suit you?
I can't remember where I originally borrowed the code to place images, I have been using it for a while now.
You could change or replace this place smart object code, or by adding an extra step to resize the placed image to fit to the canvas width should be workable. I am presuming that the original images are all larger than the artboards so scaling them up and losing quality will not be an issue.
Copy link to clipboard
Copied
How would I get the images to center on templates when added by the script? Right now, they are left justified, half way off the template when they are loaded in.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Yes, I want version A, where the artboards don't need to be chosen, it just automatically duplicates to the named artboards, but the centering from version B, Version B, I have to choose the artboard, which I can see a lot of people making a mistake with that.
Copy link to clipboard
Copied
Do you know how to achieve this?
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
Hmm.. For some reason v1.1 still has a dialog box that pops up asking where to duplicate the images. It's running exactly like the v1.0b script. v1.0 is the only one where is just duplicates to each folder automatically without a dialog asking me which one.
Copy link to clipboard
Copied
Now the original script is centering the images once I added the create document script, weird, so that is resolved.
I was able to figure out how to add script to create the document, then it adds the images with this. So it works up until this point. Once I add the renaming script it stops working.
Copy link to clipboard
Copied
Nevermind, I think i got it! =D
Copy link to clipboard
Copied
So, all of the scripts work independently, I am trying to figure out how to put them together into one script
Copy link to clipboard
Copied
Anne24506383rxky wrote:
So, all of the scripts work independently, I am trying to figure out how to put them together into one script
Three options that I can think of:
1) Record each script as a separate step into an action, then play the action. If this will be shared and used on other computers, the .jsx files would need to be run from an installed state and not browsed when recording the action so that they have a relative path to only the script file and not the entire browse path.
2) A script can do similar, one script can run the separate scripts sequentially just as an action can.
3) Combine the separate code into one single code. This could be as simple as simply pasting the different code one after the other into a single file, however, it may not be that simple.
Copy link to clipboard
Copied
Right now, I made a code to run each script as an action and that works, but it’s not functional to hand off to other coworkers who don’t know how to set the actions up.
Get Outlook for iOS<>
Copy link to clipboard
Copied
Anne24506383rxky wrote:
Right now, I made a code to run each script as an action and that works, but it’s not functional to hand off to other coworkers who don’t know how to set the actions up.
If you install the scripts in the application/program folder and restart Photoshop, they will appear in the scripts menu. Recorded action steps will simply use the name of the installed script, making this work as expected, cross-platform on multiple computers. This of course has the dependency on having both the scripts and action installed.