Copy link to clipboard
Copied
Hi, I am searching for a way or perhaps a script to enable me to export all artboards from several open PSD files at once (and not individually for each single PSD). Does anyone know if such a script exits and where I can find it?
Copy link to clipboard
Copied
Some scripts can be recorded into an action and the script parameters are also recorded for uninterrupted batch playback on all open files. Perhaps the Artboards to files script can be recorded into such a fashion, I've never tried.
I'll need to have a dig around my archive and see if I have such a script or if one can be easily modified without requiring a total rewrite.
It's generally more efficient to batch a folder of files one at a time than to batch all open files which chew up memory.
What is the save format?
What about naming? Filename + Artboard name? Are all unique or is there a possibility of the same names being used?
Copy link to clipboard
Copied
Thanks in advance for your efforts.
It's generally more efficient to batch a folder of files one at a time than to batch all open files which chew up memory.
That is right and would also work. My point is to be able to do the export for dozens of generated photoshop files in one step at a time to automate production of ad variants of a campaign.
Copy link to clipboard
Copied
Thanks for clarifying.
What is the save format?
What about naming? Filename + Artboard name? Are all artboard names unique, or is there a possibility of the same names being used?
EDIT: As a proof of concept, I have tested my "Artboards-to-WEBP-PS2025-v2.jsx" script, removing all interactive features (prompts, alerts etc.) so that it is suitable for "headless" operation when recorded into an Action and run via File > Automate > Batch... and it works great! But if you don't want WebP, then I need to know the format
Copy link to clipboard
Copied
Hi Stephen, thank you for the reply. Output-Formt should be JPG and ideally we can export the artboards with their name (and perhaps the artboards of each PSD in a single Assets-folder)
Copy link to clipboard
Copied
Hi Stephen, thank you for the reply. Output-Formt should be JPG and ideally we can export the artboards with their name (and perhaps the artboards of each PSD in a single Assets-folder)
By @Norbert252184170tz6
Try this v1.1 script, it is intended to be recorded into a 2-step action:
1) Run script
2) Close (without saving)
Then the File > Automate > Batch command should reference the action (no need to set a destination, only the source as open docs, or a folder etc).
I'm happy to make modifications based on your feedback.
/*
Artboards-to-JPEG-Headless-v1-1.jsx
Stephen Marsh
v1.0 - 25th August 2025: Initial release
v1.1 - 27th August 2025: Changed the save to create and use an "Assets" folder
* Intended for recording into an Action, then run via Automate > Batch
* Generates a log.txt file listing all successfully exported filenames
* Automatically exports all artboards from the active Photoshop document as JPEG files
* Saves exported files to the source document's folder (if saved) or Desktop as fallback location
* Creates an "Assets" folder to hold the files and log
* Creates filenames using document name prefix plus artboard name with special characters sanitized
* Implements automatic version numbering (_v001, _v002, etc.) to prevent filename conflicts
* Converts documents to RGB color mode and 8-bit depth for consistent JPEG output
* Applies sRGB color profile conversion using multiple fallback methods
* Strips all metadata (XMP, Camera Raw, Document Ancestors) from exported files
Headless batch-friendly version (no prompts, alerts or UI)
https://community.adobe.com/t5/photoshop-ecosystem-discussions/mass-export-of-artboards-from-several-open-psd-files-at-once/td-p/15471119
Based on:
https://community.adobe.com/t5/photoshop-ecosystem-discussions/exporting-artboards-to-webp-format/m-p/15431202/page/2#U15425799
*/
#target photoshop
(function () {
try {
// Exit if no document is open or no artboards are present
if (app.documents.length === 0 || !hasArtboards()) return;
// Document variable
var doc = app.activeDocument;
// Set output folder to document folder if saved, otherwise Desktop
var baseFolder = (doc.saved) ? doc.fullName.parent : Folder("~/Desktop");
// Create Assets folder
var outputFolder = new Folder(baseFolder + "/Assets");
if (!outputFolder.exists) {
outputFolder.create();
}
// Create filename prefix from document name
var preFix = doc.name.replace(/\.[^\.]+$/, '').replace(/ /g, '-') + "_";
// Duplicate the document for safe processing
doc.duplicate(doc.name.replace(/\.[^\.]+$/, '').replace(/ /g, '-'), false);
// If the doc isn't in RGB mode, convert it
if (activeDocument.mode !== DocumentMode.RGB) {
activeDocument.changeMode(ChangeMode.RGB);
}
// Ensure 8-bit depth
activeDocument.bitsPerChannel = BitsPerChannelType.EIGHT;
// More robust sRGB conversion
try {
activeDocument.convertProfile("sRGB IEC61966-2.1", Intent.RELATIVECOLORIMETRIC, true, false);
} catch (e1) {
try {
activeDocument.convertProfile("sRGB", Intent.RELATIVECOLORIMETRIC, true, false);
} catch (e2) {
try {
var idAssignProfile = stringIDToTypeID("assignProfile");
var desc1 = new ActionDescriptor();
desc1.putString(stringIDToTypeID("profile"), "sRGB IEC61966-2.1");
executeAction(idAssignProfile, desc1, DialogModes.NO);
} catch (e3) {
try {
var idConvertToProfile = stringIDToTypeID("convertToProfile");
var desc2 = new ActionDescriptor();
desc2.putString(stringIDToTypeID("profile"), "sRGB IEC61966-2.1");
desc2.putEnumerated(stringIDToTypeID("intent"), stringIDToTypeID("intent"), stringIDToTypeID("relativeColorimetric"));
desc2.putBoolean(stringIDToTypeID("blackPointCompensation"), true);
desc2.putBoolean(stringIDToTypeID("dither"), false);
executeAction(idConvertToProfile, desc2, DialogModes.NO);
} catch (e4) {
// If all methods fail, continue without conversion
}
}
}
}
// Remove metadata
deleteDocumentAncestorsMetadata();
removeCRSmeta();
removeXMP();
var dupedDoc = app.activeDocument;
var dupedDoclayerSets = app.activeDocument.layerSets;
// Loop through artboards and export each one
for (var i = dupedDoclayerSets.length - 1; i >= 0; i--) {
var currentSet = dupedDoclayerSets[i];
dupedDoc.activeLayer = currentSet;
if (isArtboard()) {
dupeActiveLayer(currentSet.name, currentSet.name);
app.activeDocument.trim(TrimType.TRANSPARENT);
var baseName = preFix + app.activeDocument.activeLayer.name.replace(/[:\/\\*\?\"\<\>\|\\\r\\\n. ]/g, "-");
var artboardName = getUniqueFilename(baseName, outputFolder);
saveAsJPEG(artboardName);
logExportedFile(artboardName);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}
}
dupedDoc.close(SaveOptions.DONOTSAVECHANGES);
function hasArtboards() {
for (var i = 0; i < activeDocument.layerSets.length; i++) {
activeDocument.activeLayer = activeDocument.layerSets[i];
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID('layer'), stringIDToTypeID('ordinal'), stringIDToTypeID('targetEnum'));
var options = executeActionGet(r);
if (options.hasKey(stringIDToTypeID('artboard'))) return true;
}
return false;
}
function isArtboard() {
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID('layer'), stringIDToTypeID('ordinal'), stringIDToTypeID('targetEnum'));
var options = executeActionGet(r);
return options.hasKey(stringIDToTypeID('artboard'));
}
function dupeActiveLayer(docName, layerName) {
var c2t = function (s) { return app.charIDToTypeID(s); };
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(c2t("null"), reference);
descriptor.putString(s2t("name"), docName);
reference2.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
descriptor.putReference(s2t("using"), reference2);
descriptor.putString(s2t("layerName"), layerName);
executeAction(s2t("make"), descriptor, DialogModes.NO);
}
function getUniqueFilename(baseName, folderPath) {
var version = 1;
var fileName = baseName;
var file = new File(folderPath + '/' + fileName + '.jpg');
while (file.exists) {
var paddedVersion = ("000" + version).slice(-3);
fileName = baseName + "_v" + paddedVersion;
file = new File(folderPath + '/' + fileName + '.jpg');
version++;
}
return fileName;
}
function saveAsJPEG(_name) {
var jpgOptns = new JPEGSaveOptions();
jpgOptns.formatOptions = FormatOptions.STANDARDBASELINE;
jpgOptns.embedColorProfile = true;
jpgOptns.matte = MatteType.NONE;
jpgOptns.quality = 9;
activeDocument.saveAs(new File(outputFolder + '/' + _name + '.jpg'), jpgOptns, true, Extension.LOWERCASE);
}
function logExportedFile(fileName) {
var logFile = new File(outputFolder + "/log.txt");
logFile.open("a");
logFile.writeln(fileName + ".jpg");
logFile.close();
}
function removeXMP() {
if (!documents.length) return;
if (ExternalObject.AdobeXMPScript === undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
var xmp = new XMPMeta(activeDocument.xmpMetadata.rawData);
XMPUtils.removeProperties(xmp, "", "", XMPConst.REMOVE_ALL_PROPERTIES);
app.activeDocument.xmpMetadata.rawData = xmp.serialize();
}
function removeCRSmeta() {
if (!documents.length) return;
if (ExternalObject.AdobeXMPScript === undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
var xmp = new XMPMeta(app.activeDocument.xmpMetadata.rawData);
XMPUtils.removeProperties(xmp, XMPConst.NS_CAMERA_RAW, "", XMPConst.REMOVE_ALL_PROPERTIES);
app.activeDocument.xmpMetadata.rawData = xmp.serialize();
}
function deleteDocumentAncestorsMetadata() {
if (ExternalObject.AdobeXMPScript === undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
var xmp = new XMPMeta(activeDocument.xmpMetadata.rawData);
xmp.deleteProperty(XMPConst.NS_PHOTOSHOP, "DocumentAncestors");
app.activeDocument.xmpMetadata.rawData = xmp.serialize();
}
} catch (e) {
// Fail silently in headless mode
}
})();
https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html
Copy link to clipboard
Copied
Hi, I will try it as soon as I can. But it may last a while as we are currently focussing on different projects and campaigns. So at the moment there are other more important jobs to do. But I will do further tests, when I have the time to do so. Thank you for your feedback and best regards.
Copy link to clipboard
Copied
@Norbert252184170tz6 - OK, let me know how it goes once the priorities shift.
Find more inspiration, events, and resources on the new Adobe Community
Explore Now