Multiple WEBP Conversion Script with Recursion
Hi All I've tried getting help on this in multiple places in the community but I think I'm posting in the wrong places. So I'll try here in a new post.
I've taken 2 scripts created by @Stephen Marsh and combined them. The first is a script he wrote to convert files to WEBP and the second is a script with recursive folder process which was created to resize existing WEBP images.
For the most part my hybrid seems to work fine but it's failing when processing smaller images whether this is dimensions or file size I'm not entirely sure.
At first I though this was only a PNG issue so altered to skip them but the problem still exists.
If an expert could take a look and help I'd be so grateful.
/*
Batch Save As WebP 1000px Wide.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/looking-for-action-or-script-to-resize-and-save-webp-files/td-p/14282886
v1.1 - 8th December 2023, Stephen Marsh
Special thanks to Paul MR for the recursive folder processing code:
photoshopgurus.com/forum/threads/batch-and-subfolders.22134/
*/
#target photoshop
(function () {
if (app.documents.length === 0) {
// Ensure that version 2022 or later is being used
var versionNumber = app.version.split(".");
var versionCheck = parseInt(versionNumber);
// Fail
if (versionCheck < 23) {
alert("You must use Photoshop 2022 or later to save using native WebP format...");
return;
// Pass
} else {
if (confirm('All sub-folders under the selected input folder will be processed. Continue?', false)) {
var imageFolder = Folder.selectDialog('Select the top-level folder:');
var outputFolder = Folder.selectDialog("Please select the output folder:");
var origDialogs = app.displayDialogs;
app.displayDialogs = DialogModes.NO;
// Script Execution Timer - Function
var timeDiff = {
setStartTime: function () {
d = new Date();
time = d.getTime();
},
getDiff: function () {
d = new Date();
t = d.getTime() - time;
time = d.getTime();
return t;
}
};
// Script Execution Timer - Start
timeDiff.setStartTime();
// Set the file processing counter
var fileCounter = 0;
if (imageFolder != null) processFolder(imageFolder);
function processFolder(folder) {
var fileList = folder.getFiles()
for (var i = 0; i < fileList.length; i++) {
var file = fileList[i];
if (file instanceof File && file.name.match(/\.(tif|tiff|jpg|jpeg|psd|psb)/i)) {
open(file);
if (activeDocument.mode !== DocumentMode.RGB) {
// Convert to sRGB & 8 bpc
activeDocument.convertProfile("sRGB IEC61966-2.1", Intent.RELATIVECOLORIMETRIC, true, false);
activeDocument.bitsPerChannel = BitsPerChannelType.EIGHT;
// Run the optional action
//app.doAction(actionName, actionSet);
// Save as a copy and close
saveWebP("compressionLossy", 75, true, true, true, true);
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
// Increment the file saving counter
fileCounter++;
// If the doc is in RGB mode
} else {
// Convert to sRGB & 8 bpc
//activeDocument.convertProfile("sRGB IEC61966-2.1", Intent.RELATIVECOLORIMETRIC, true, false);
activeDocument.bitsPerChannel = BitsPerChannelType.EIGHT;
// Run the optional action
//app.doAction(actionName, actionSet);
// Save as a copy and close
saveWebP("compressionLossy", 75, true, true, true, true);
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
// Increment the file saving counter
fileCounter++;
}
// // Start Main Code Block
// activeDocument.resizeImage(UnitValue(1000, "px"), null, null, ResampleMethod.BICUBIC); // width, height, resolution, method
// activeDocument.close(SaveOptions.SAVECHANGES);
// fileCounter++;
// End Main Code Block
} else
if (file instanceof Folder) {
outputFolder = file;
processFolder(file);
}
}
}
// End of script
app.displayDialogs = origDialogs;
alert('Batch resize and WebP overwrite completed!' + '\r' + fileCounter + ' WebP files processed' + '\r' + '(' + timeDiff.getDiff() / 1000 + ' seconds)');
}
}
} else {
alert('Please close all open documents before running this script!');
}
function saveWebP(compType, compValue, xmpData, exifData, psData, asCopy) {
/*
v1.1 - 12th March 2023, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/saving-webp-image-by-script/td-p/13642577
*/
// Doc and path save variables
var WebPDocName = activeDocument.name.replace(/\.[^\.]+$/, ''); // Remove file extension
var WebPSavePath = outputFolder + "/" + WebPDocName + ".webp" // Change path as needed
var WebPFile = new File(WebPSavePath); // Create the file object
// //
// // // check for existing file object
// // if (webpfile.exists) {
// // // true = 'no' as default active button
// // if (!confirm("file exists, overwrite: yes or no?", true))
// // // throw alert("script cancelled!");
// // throw null;
// // }
// //
function s2t(s) {
return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
// Compression parameters = "compressionLossless" | "compressionLossy"
descriptor2.putEnumerated(s2t("compression"), s2t("WebPCompression"), s2t(compType)); // string variable
var WebPCompIsLossless = false; // set the default flag for compression
if (WebPCompIsLossless == false) {
// 0 (lowest lossy quality) - 100 (highest lossy quality)
descriptor2.putInteger(s2t("quality"), compValue); // number variable
}
// Metadata options
descriptor2.putBoolean(s2t("includeXMPData"), xmpData); // Boolean param moved to function call
descriptor2.putBoolean(s2t("includeEXIFData"), exifData); // Boolean param moved to function call
descriptor2.putBoolean(s2t("includePsExtras"), psData); // Boolean param moved to function call
// WebP format and save path
descriptor.putObject(s2t("as"), s2t("WebPFormat"), descriptor2);
descriptor.putPath(s2t("in"), WebPFile); // Save path variable
// Save As = false | Save As a Copy = true
descriptor.putBoolean(s2t("copy"), asCopy); // Boolean param moved to function call
// The extension
descriptor.putBoolean(s2t("lowerCase"), true);
// Execute the save
executeAction(s2t("save"), descriptor, DialogModes.NO); // Change NO to ALL for dialog
}
}());
