Copy link to clipboard
Copied
I have created an "Artboards to AVIF" script, based on my "Artboards to WebP" script.
/*
Artboards-to-AVIF-PS2025-scriptUI-GUI-v1-0.jsx
Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/artboards-to-avif-script/m-p/15480083
v1.0 - 30th July 2025: Initial release
* Only for Photoshop 2025 (v26.x.x) or later!
* Saves artboards as AVIF with lossless/lossy quality options
* Resize artboard by % option, a filename suffix such as '_200' is added to indicate a 200% resize
* Filename word spaces (%20) are converted to web-friendly hyphens
* Artboard content is constrained to the artboard bounds
* Metadata is removed and the document ICC profile is embedded
* Optional JPEG save checkbox with quality level dropdown menu
* Option to overwrite existing files or to add a date-timestamp suffix '_YYYYMMDD-HHMMSS'
* Optionally convert RGB images to sRGB color profile, RGB color mode and 8 bpc (non-RGB images are automatically converted to sRGB 8 BPC)
Based on:
Artboards-to-WEBP-PS2025-scriptUI-GUI-v2-1.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/exporting-artboards-to-webp-format/td-p/12937135#U15431202
*/
#target photoshop
(function () {
try {
app.bringToFront();
var versionNumber = app.version.split(".");
var versionCheck = parseInt(versionNumber);
if (versionCheck < 26) {
alert("You must use Photoshop 2025 or later to save using native AVIF format...");
return;
}
if (app.documents.length === 0) {
alert("Please open a document first!");
return;
}
var doc = app.activeDocument;
var layerSets = doc.layerSets;
try {
var docPath = app.activeDocument.path;
} catch (e) {
docPath = Folder("~/Desktop");
}
if (!hasArtboards()) {
alert("No artboards found, script canceled!");
return;
}
var exportSettings = {
outputFolder: docPath,
prefix: doc.name.replace(/\.[^\.]+$/, '').replace(/ /g, '-') + "_",
quality: 50,
isLossy: true,
overwrite: true,
openFolder: true,
enableResize: false,
resizeWidth: 200,
scaleStyles: true,
constrainProportions: true,
jpegQuality: 9,
saveJPEG: true
};
var dlg = new Window("dialog", "Export Artboards to AVIF (v1.0)");
dlg.orientation = "column";
dlg.alignChildren = ["fill", "top"];
dlg.spacing = 10;
dlg.margins = 16;
var settingsGroup = dlg.add("panel", undefined, "");
settingsGroup.orientation = "column";
settingsGroup.alignChildren = ["fill", "top"];
settingsGroup.margins = 10;
settingsGroup.spacing = 8;
var folderGroup = settingsGroup.add("group");
folderGroup.orientation = "column";
folderGroup.alignChildren = ["fill", "top"];
folderGroup.add("statictext", undefined, "Output folder:");
var folderSubGroup = folderGroup.add("group");
var browseBtn = folderSubGroup.add("button", undefined, "Browse...");
var folderText = folderSubGroup.add("statictext", undefined, exportSettings.outputFolder ? decodeURI(exportSettings.outputFolder.fsName) : "None selected", { truncate: 'middle' });
folderText.alignment = ["fill", "left"];
browseBtn.onClick = function () {
var folder = Folder.selectDialog("Select Output Folder");
if (folder) {
exportSettings.outputFolder = folder;
folderText.text = decodeURI(folder.fsName);
}
};
var prefixGroup = settingsGroup.add("group");
prefixGroup.orientation = "column";
prefixGroup.alignChildren = ["fill", "top"];
prefixGroup.add("statictext", undefined, "Filename prefix:");
var prefixInput = prefixGroup.add("edittext", undefined, exportSettings.prefix);
prefixInput.characters = 30;
var compGroup = settingsGroup.add("group");
compGroup.orientation = "column";
compGroup.alignChildren = ["fill", "top"];
var radioGroup = compGroup.add("group");
radioGroup.orientation = "row";
radioGroup.add("statictext", undefined, "Compression:");
var lossyRadio = radioGroup.add("radiobutton", undefined, "Lossy");
var losslessRadio = radioGroup.add("radiobutton", undefined, "Lossless");
lossyRadio.value = true;
var qualityGroup = compGroup.add("group");
qualityGroup.orientation = "row";
qualityGroup.alignChildren = ["left", "center"];
qualityGroup.add("statictext", undefined, "Image quality (0-100):");
var qualitySlider = qualityGroup.add("slider", undefined, exportSettings.quality, 0, 100);
qualitySlider.preferredSize.width = 150;
var qualityValue = qualityGroup.add("statictext", undefined, exportSettings.quality.toString());
qualitySlider.onChanging = function () {
qualityValue.text = Math.round(qualitySlider.value).toString();
};
qualitySlider.onChange = function () {
qualityValue.text = Math.round(qualitySlider.value).toString();
};
lossyRadio.onClick = function () {
qualitySlider.enabled = true;
qualityValue.enabled = true;
};
losslessRadio.onClick = function () {
qualitySlider.enabled = false;
qualityValue.enabled = false;
};
var resizeGroup = settingsGroup.add("group");
resizeGroup.orientation = "column";
resizeGroup.alignChildren = ["fill", "top"];
var resizeCheck = resizeGroup.add("checkbox", undefined, "Resize artboards");
resizeCheck.value = false;
var resizeOptionsGroup = resizeGroup.add("group");
resizeOptionsGroup.orientation = "row";
resizeOptionsGroup.alignChildren = ["left", "center"];
resizeOptionsGroup.enabled = false;
resizeOptionsGroup.add("statictext", undefined, "Resize %:");
var widthInput = resizeOptionsGroup.add("editnumber", undefined, exportSettings.resizeWidth.toString());
widthInput.characters = 5;
resizeCheck.onClick = function () {
resizeOptionsGroup.enabled = resizeCheck.value;
};
var checkGroup = settingsGroup.add("group");
checkGroup.orientation = "column";
checkGroup.alignChildren = ["left", "top"];
var convertRGBCheck = checkGroup.add("checkbox", undefined, "Convert to sRGB");
convertRGBCheck.value = true;
var overwriteCheck = checkGroup.add("checkbox", undefined, "Overwrite existing files");
overwriteCheck.value = true;
var openFolderCheck = checkGroup.add("checkbox", undefined, "Open folder after export");
openFolderCheck.value = false;
var jpegGroup = checkGroup.add("group");
jpegGroup.orientation = "row";
jpegGroup.alignChildren = ["left", "center"];
var saveJPEGCheck = jpegGroup.add("checkbox", undefined, "Save JPEG copy");
saveJPEGCheck.value = false;
var jpegQualityLabel = jpegGroup.add("statictext", undefined, "Quality:");
var jpegQualityDropdown = jpegGroup.add("dropdownlist", undefined, ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"]);
jpegQualityDropdown.selection = 9;
jpegQualityLabel.enabled = false;
jpegQualityDropdown.enabled = false;
saveJPEGCheck.onClick = function () {
jpegQualityLabel.enabled = saveJPEGCheck.value;
jpegQualityDropdown.enabled = saveJPEGCheck.value;
};
var btnGroup = dlg.add("group");
btnGroup.alignment = "right";
var cancelBtn = btnGroup.add("button", undefined, "Cancel");
var okBtn = btnGroup.add("button", undefined, "OK");
cancelBtn.onClick = function () { dlg.close(0); };
okBtn.onClick = function () {
if (!exportSettings.outputFolder) {
alert("Please select an output folder.");
return;
}
exportSettings.prefix = prefixInput.text;
exportSettings.quality = Math.round(qualitySlider.value);
exportSettings.isLossy = lossyRadio.value;
exportSettings.overwrite = overwriteCheck.value;
exportSettings.openFolder = openFolderCheck.value;
exportSettings.enableResize = resizeCheck.value;
exportSettings.resizeWidth = parseInt(widthInput.text) || 100;
exportSettings.saveJPEG = saveJPEGCheck.value;
if (saveJPEGCheck.value && jpegQualityDropdown.selection !== null) {
exportSettings.jpegQuality = parseInt(jpegQualityDropdown.selection.text);
}
exportSettings.convertRGB = convertRGBCheck.value;
dlg.close(1);
};
if (dlg.show() !== 1) {
app.beep();
return;
}
app.togglePalettes();
var progressWin = new Window("palette", "Processing Artboards", undefined, { closeButton: false });
progressWin.orientation = "column";
progressWin.alignChildren = ["fill", "top"];
progressWin.spacing = 10;
progressWin.margins = 16;
var progressText = progressWin.add("statictext", undefined, "Starting...");
var progressBar = progressWin.add("progressbar", undefined, 0, layerSets.length);
progressBar.preferredSize = [300, 20];
progressWin.show();
var dupedDoc = null;
var avifCounter = 0;
var jpegCounter = 0;
try {
dupedDoc = doc.duplicate(doc.name.replace(/\.[^\.]+$/, '').replace(/ /g, '-'), false);
app.activeDocument = dupedDoc;
if (activeDocument.mode !== DocumentMode.RGB) {
activeDocument.convertProfile("sRGB IEC61966-2.1", Intent.RELATIVECOLORIMETRIC, true, false);
activeDocument.changeMode(ChangeMode.RGB);
} else if (exportSettings.convertRGB) {
activeDocument.convertProfile("sRGB IEC61966-2.1", Intent.RELATIVECOLORIMETRIC, true, false);
}
activeDocument.bitsPerChannel = BitsPerChannelType.EIGHT;
deleteDocumentAncestorsMetadata();
removeCRSmeta();
removeXMP();
var dupedDoclayerSets = app.activeDocument.layerSets;
for (var i = dupedDoclayerSets.length - 1; i >= 0; i--) {
var currentSet = dupedDoclayerSets[i];
dupedDoc.activeLayer = currentSet;
progressText.text = "Processing: " + currentSet.name + " (" + (avifCounter + 1) + " of " + layerSets.length + ")";
progressBar.value = avifCounter + 1;
app.refresh();
if (isArtboard() === true) {
dupeActiveLayer(currentSet.name, currentSet.name);
trimTransparency(true, true, true, true);
if (exportSettings.enableResize && exportSettings.resizeWidth !== 100) {
imageSize(exportSettings.resizeWidth, exportSettings.scaleStyles, exportSettings.constrainProportions);
}
var artboardName = exportSettings.prefix + app.activeDocument.activeLayer.name
.replace(/[:\/\\*\?\"\<\>\|\\r\\n. ]+/g, "-")
.replace(/-+$/, '')
.replace(/^-+/, '');
if (exportSettings.enableResize) {
artboardName += "_" + exportSettings.resizeWidth.toString();
}
var finalFileName = exportSettings.overwrite ? artboardName : artboardName + "_" + getTimestamp();
saveAsAVIF(finalFileName);
if (exportSettings.saveJPEG) {
saveAsJPEG(finalFileName);
jpegCounter++;
}
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
avifCounter++;
}
}
dupedDoc.close(SaveOptions.DONOTSAVECHANGES);
} catch (e) {
alert("Unexpected error during processing:\n" + e.message + "\nLine: " + e.line);
} finally {
try {
if (dupedDoc && app.documents.length && app.documents.indexOf(dupedDoc) !== -1) {
dupedDoc.close(SaveOptions.DONOTSAVECHANGES);
}
} catch (e) { }
app.bringToFront();
progressWin.close();
app.togglePalettes();
}
app.beep();
alert((avifCounter + jpegCounter) + ' files saved to: ' + '\r' + exportSettings.outputFolder.fsName);
if (exportSettings.openFolder) {
exportSettings.outputFolder.execute();
}
////// FUNCTIONS //////
function imageSize(width, scaleStyles, constrainProportions) {
var s2t = function (s) { return app.stringIDToTypeID(s); };
var descriptor = new ActionDescriptor();
descriptor.putUnitDouble(s2t("width"), s2t("percentUnit"), width);
descriptor.putBoolean(s2t("scaleStyles"), scaleStyles);
descriptor.putBoolean(s2t("constrainProportions"), constrainProportions);
executeAction(s2t("imageSize"), descriptor, DialogModes.NO);
}
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() {
try {
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID('layer'), stringIDToTypeID('ordinal'), stringIDToTypeID('targetEnum'));
var options = executeActionGet(r);
return options.hasKey(stringIDToTypeID('artboard'));
} catch (e) {
alert("Error:\n" + e.message + "\nLine: " + e.line);
}
}
function dupeActiveLayer(docName, layerName) {
try {
var s2t = function (s) { return stringIDToTypeID(s); };
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
var reference2 = new ActionReference();
reference.putClass(s2t("document"));
descriptor.putReference(charIDToTypeID("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);
} catch (e) {
alert("Error:\n" + e.message + "\nLine: " + e.line);
}
}
function trimTransparency(top, bottom, left, right) {
try {
var c2t = function (s) { return charIDToTypeID(s); };
var s2t = function (s) { return stringIDToTypeID(s); };
var descriptor = new ActionDescriptor();
descriptor.putEnumerated(s2t("trimBasedOn"), s2t("trimBasedOn"), c2t("Trns"));
descriptor.putBoolean(s2t("top"), top);
descriptor.putBoolean(s2t("bottom"), bottom);
descriptor.putBoolean(s2t("left"), left);
descriptor.putBoolean(s2t("right"), right);
executeAction(s2t("trim"), descriptor, DialogModes.NO);
} catch (e) {
alert("Error:\n" + e.message + "\nLine: " + e.line);
}
}
function removeCRSmeta() {
try {
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();
} catch (e) {
alert("Error:\n" + e.message + "\nLine: " + e.line);
}
}
function deleteDocumentAncestorsMetadata() {
try {
if (!documents.length) return;
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) {
alert("Error:\n" + e.message + "\nLine: " + e.line);
}
}
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 saveAsAVIF(saveName) {
try {
var s2t = function (s) { return stringIDToTypeID(s); };
var descSave = new ActionDescriptor();
var descAVIFOptions = new ActionDescriptor();
var idAVIFCompression = s2t("AVIFCompression");
if (exportSettings.isLossy) {
descAVIFOptions.putEnumerated(s2t("colorCompression"), idAVIFCompression, s2t("compressionLossy"));
descAVIFOptions.putInteger(s2t("colorQuality"), exportSettings.quality);
} else {
descAVIFOptions.putEnumerated(s2t("colorCompression"), idAVIFCompression, s2t("compressionLossless"));
}
descAVIFOptions.putEnumerated(s2t("alphaCompression"), idAVIFCompression, s2t("compressionLossless"));
descAVIFOptions.putEnumerated(s2t("colorFormat"), s2t("AVIFColorFormat"), s2t("AVIFFormat422")); // Options: AVIFFormat444, AVIFFormat422, AVIFFormat420
descAVIFOptions.putEnumerated(s2t("sampleDepth"), s2t("AVIFSampleDepth"), s2t("AVIFDepth12bit"));
descAVIFOptions.putInteger(s2t("encoderSpeed"), 6); // Options: 2 (slowest/smallest), 4, 6, 8, 10 (fastest/largest)
descAVIFOptions.putBoolean(s2t("includeXMPData"), false);
descAVIFOptions.putBoolean(s2t("includeEXIFData"), false);
descAVIFOptions.putBoolean(s2t("includePsExtras"), false);
descSave.putObject(s2t("as"), s2t("AVIFFormat"), descAVIFOptions);
descSave.putPath(s2t("in"), new File(exportSettings.outputFolder + '/' + saveName + '.avif'));
descSave.putBoolean(s2t("lowerCase"), true);
descSave.putEnumerated(s2t("saveStage"), s2t("saveStageType"), s2t("saveSucceeded"));
executeAction(s2t("save"), descSave, DialogModes.NO);
} catch (e) {
alert("Error saving AVIF:\n" + e.message + "\nLine: " + e.line);
}
}
function saveAsJPEG(_name) {
var jpgOptns = new JPEGSaveOptions();
jpgOptns.formatOptions = FormatOptions.STANDARDBASELINE;
jpgOptns.embedColorProfile = true;
jpgOptns.matte = MatteType.NONE;
jpgOptns.quality = exportSettings.jpegQuality || 9;
activeDocument.saveAs(new File(exportSettings.outputFolder + '/' + _name + '.jpg'), jpgOptns, true, Extension.LOWERCASE);
}
function getTimestamp() {
var now = new Date();
return now.getFullYear().toString() +
("0" + (now.getMonth() + 1)).slice(-2) +
("0" + now.getDate()).slice(-2) + "-" +
("0" + now.getHours()).slice(-2) +
("0" + now.getMinutes()).slice(-2) +
("0" + now.getSeconds()).slice(-2);
}
} catch (e) {
alert("Error:\n" + e.message + "\nLine: " + e.line);
}
})();
https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html
Copy link to clipboard
Copied
@Stephen Marsh nice job!
Copy link to clipboard
Copied
@creative explorer - thank you!
Find more inspiration, events, and resources on the new Adobe Community
Explore Now