filiped18684219
Community Beginner
filiped18684219
Community Beginner
Activity
‎Sep 14, 2024
01:42 PM
Wow! That's another level!
... View more
‎Sep 13, 2024
05:59 AM
You're welcome as well! One last contribution: this one sets the output folder automatically to a webp subfolder in the input folder if the user don't choose an output folder. It saves a bit more of time 😃 /*
Batch Save As WebP.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/export-many-files-at-once-in-webp-format-photoshop/m-p/13604411
v1.0 - 14th March 2023, Stephen Marsh
v1.1 - 11th January 2024: Added a "fit image" to 1920px step
v1.2 - 10th February 2024: Added an explicit step to change to RGB mode for non-RGB images
v1.3 - 12th September 2024: Added ScriptUI with inputs for input/output folders, max image size, resolution and quality
*/
#target photoshop
// Ensure that version 2022 or later is being used
var versionNumber = app.version.split(".");
var versionCheck = parseInt(versionNumber);
// Fail if Photoshop version is less than 2022
if (versionCheck < 23) {
alert("You must use Photoshop 2022 or later to save using native WebP format...");
} else {
// Create the ScriptUI dialog
var dialog = new Window("dialog", "Batch Save As WebP");
// Create a panel to hold the input fields
var mainPanel = dialog.add("panel");
mainPanel.orientation = "column";
mainPanel.alignChildren = "left";
// Input folder selection
var inputGroup = mainPanel.add("group");
inputGroup.orientation = "row";
inputGroup.add("statictext", undefined, "Input Folder:");
var inputFolderInput = inputGroup.add("edittext", undefined, "");
inputFolderInput.characters = 30;
var inputBrowseButton = inputGroup.add("button", undefined, "Browse...");
// Output folder selection
var outputGroup = mainPanel.add("group");
outputGroup.orientation = "row";
outputGroup.add("statictext", undefined, "Output Folder:");
var outputFolderInput = outputGroup.add("edittext", undefined, "[Input Folder]/webp");
outputFolderInput.characters = 30;
var outputBrowseButton = outputGroup.add("button", undefined, "Browse...");
// Maximum image size
var sizeGroup = mainPanel.add("group");
sizeGroup.orientation = "row";
sizeGroup.add("statictext", undefined, "Max Image Size (px):");
var maxSizeInput = sizeGroup.add("editnumber", undefined, "1920");
maxSizeInput.characters = 10;
// Resolution input
var resolutionGroup = mainPanel.add("group");
resolutionGroup.orientation = "row";
resolutionGroup.add("statictext", undefined, "Resolution (DPI):");
var resolutionInput = resolutionGroup.add("editnumber", undefined, "72");
resolutionInput.characters = 10;
// Compression quality
var qualityGroup = mainPanel.add("group");
qualityGroup.orientation = "row";
qualityGroup.add("statictext", undefined, "Quality (0-100):");
var qualityInput = qualityGroup.add("editnumber", undefined, "75");
qualityInput.characters = 10;
// OK and Cancel buttons
var buttonGroup = dialog.add("group");
buttonGroup.orientation = "row";
var okButton = buttonGroup.add("button", undefined, "OK");
var cancelButton = buttonGroup.add("button", undefined, "Cancel");
// OutputFolderInput Placeholder behavior
outputFolderInput.onSetFocus = function () {
if (outputFolderInput.text === "[Input Folder]/webp") {
outputFolderInput.text = "";
}
};
outputFolderInput.onKillFocus = function () {
if (outputFolderInput.text === "") {
outputFolderInput.text = "[Input Folder]/webp";
}
};
// Folder browsing functionality
inputBrowseButton.onClick = function () {
var inputFolder = Folder.selectDialog("Select the input folder:");
if (inputFolder) {
inputFolderInput.text = inputFolder.fsName;
}
};
outputBrowseButton.onClick = function () {
var outputFolder = Folder.selectDialog("Select the output folder:");
if (outputFolder) {
outputFolderInput.text = outputFolder.fsName;
}
};
// OK button action
okButton.onClick = function () {
var inputFolder = Folder(inputFolderInput.text);
var outputFolder = Folder(inputFolder.fsName + '/webp');
if (outputFolderInput.text !== "[Input Folder]/webp"
&& outputFolderInput.text !== ""
) {
outputFolder = Folder(outputFolderInput.text);
}
var maxSize = parseInt(maxSizeInput.text) || 1920;
var resolution = parseInt(resolutionInput.text) || 72;
var quality = parseInt(qualityInput.text) || 75;
// Ensure input/output folders are set
if (!inputFolder.exists) {
alert("Please select valid input folder.");
return;
}
// Create the output folder if needed
if (!outputFolder.exists) {
outputFolder.create();
}
dialog.close(1); // Close the dialog with "OK"
processFiles(inputFolder, outputFolder, maxSize, resolution, quality);
};
// Cancel button action
cancelButton.onClick = function () {
dialog.close(0); // Close the dialog with "Cancel"
};
// Show the dialog
if (dialog.show() == 1) {
// Continue processing if OK is pressed
} else {
// Do nothing if Cancel is pressed
}
// Main function to process the files
function processFiles(inputFolder, outputFolder, maxSize, resolution, quality) {
// Limit the input files, add or remove extensions as required
var fileList = inputFolder.getFiles(/\.(webp|tif|tiff|jpg|jpeg|psd|psb|png)$/i);
fileList.sort();
var savedDisplayDialogs = app.displayDialogs;
app.displayDialogs = DialogModes.NO;
// Set the file processing counter
var fileCounter = 0;
// Process the input files
for (var i = 0; i < fileList.length; i++) {
var doc = open(fileList[i]);
// If the doc isn't in RGB mode
if (activeDocument.mode !== DocumentMode.RGB) {
activeDocument.convertProfile("sRGB IEC61966-2.1", Intent.RELATIVECOLORIMETRIC, true, false);
activeDocument.changeMode(ChangeMode.RGB);
activeDocument.bitsPerChannel = BitsPerChannelType.EIGHT;
}
// Fit image to the specified max size
fitImage(maxSize, maxSize, resolution);
// Save as WebP and close
saveWebP(outputFolder, quality, true, true, true, true);
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
// Increment the file saving counter
fileCounter++;
}
// Function to resize image based on dimensions and resolution
function fitImage(fWidth, fHeight, resolution) {
if (activeDocument.height.value > activeDocument.width.value) {
activeDocument.resizeImage(null, UnitValue(fHeight, "px"), resolution, ResampleMethod.BICUBIC);
} else {
activeDocument.resizeImage(UnitValue(fWidth, "px"), null, resolution, ResampleMethod.BICUBIC);
}
}
app.displayDialogs = savedDisplayDialogs;
alert('Script completed!' + '\n' + fileCounter + ' files saved to:' + '\r' + outputFolder.fsName);
}
// Function to save as WebP
function saveWebP(outputFolder, quality, xmpData, exifData, psData, asCopy) {
var WebPDocName = activeDocument.name.replace(/\.[^\.]+$/, ''); // Remove file extension
var WebPSavePath = outputFolder + "/" + WebPDocName + ".webp"; // Define save path
var WebPFile = new File(WebPSavePath); // Create file object
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("compressionLossy")); // Lossy compression
descriptor2.putInteger(s2t("quality"), quality); // Set quality (0-100)
// Metadata options
descriptor2.putBoolean(s2t("includeXMPData"), xmpData);
descriptor2.putBoolean(s2t("includeEXIFData"), exifData);
descriptor2.putBoolean(s2t("includePsExtras"), psData);
// WebP format and save path
descriptor.putObject(s2t("as"), s2t("WebPFormat"), descriptor2);
descriptor.putPath(s2t("in"), WebPFile);
// Save As a Copy
descriptor.putBoolean(s2t("copy"), asCopy);
descriptor.putBoolean(s2t("lowerCase"), true);
// Execute save action
executeAction(s2t("save"), descriptor, DialogModes.NO);
}
}
... View more
‎Sep 13, 2024
05:06 AM
Nice! Oh, and thank you for making this awesome script! It's saving me a lot of time.
... View more
‎Sep 12, 2024
06:52 PM
1 Upvote
I used several prompts because I made the first prompt before testing the original script and the resulting script ended opening up a prompt to each input field 😂 I pasted the previous code and added this prompt: The script for photoshop below serves to convert images into webp. Change it to display text fields to set the maximum image size (keeping the default value in 1920px) and resolution (standard at 72). Then it took 3 more prompts to get to the result I posted: This script opens several prompts one followed by the other. Is it possible to display only one window with all the inputs? Redo by also inserting in the dialog window a field to define image quality in compression and the input folder and output folder selection fields Is it possible to insert the labels of the fields next to the respective fields, the Browse buttons next to the respective text fields, and the OK and Cancel buttons next to each other? I tried to make the layout more organized, align the labels and inputs like a table where the first column has the labels and the second has the inputs, but it didn't worked out.
... View more
‎Sep 12, 2024
05:29 PM
2 Upvotes
I used chatGPT to add a UI with inputs to customize maxsize, resolution and compression quality: /*
Batch Save As WebP.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/export-many-files-at-once-in-webp-format-photoshop/m-p/13604411
v1.0 - 14th March 2023, Stephen Marsh
v1.1 - 11th January 2024: Added a "fit image" to 1920px step
v1.2 - 10th February 2024: Added an explicit step to change to RGB mode for non-RGB images
v1.3 - 12th September 2024: Added ScriptUI and user input for max image size, resolution and quality
*/
#target photoshop
// Ensure that version 2022 or later is being used
var versionNumber = app.version.split(".");
var versionCheck = parseInt(versionNumber);
// Fail if Photoshop version is less than 2022
if (versionCheck < 23) {
alert("You must use Photoshop 2022 or later to save using native WebP format...");
} else {
// Create the ScriptUI dialog
var dialog = new Window("dialog", "Batch Save As WebP");
// Create a panel to hold the input fields
var mainPanel = dialog.add("panel");
mainPanel.orientation = "column";
mainPanel.alignChildren = "left";
// Input folder selection
var inputGroup = mainPanel.add("group");
inputGroup.orientation = "row";
inputGroup.add("statictext", undefined, "Input Folder:");
var inputFolderInput = inputGroup.add("edittext", undefined, "");
inputFolderInput.characters = 30;
var inputBrowseButton = inputGroup.add("button", undefined, "Browse...");
// Output folder selection
var outputGroup = mainPanel.add("group");
outputGroup.orientation = "row";
outputGroup.add("statictext", undefined, "Output Folder:");
var outputFolderInput = outputGroup.add("edittext", undefined, "");
outputFolderInput.characters = 30;
var outputBrowseButton = outputGroup.add("button", undefined, "Browse...");
// Maximum image size
var sizeGroup = mainPanel.add("group");
sizeGroup.orientation = "row";
sizeGroup.add("statictext", undefined, "Max Image Size (px):");
var maxSizeInput = sizeGroup.add("edittext", undefined, "1920");
maxSizeInput.characters = 10;
// Resolution input
var resolutionGroup = mainPanel.add("group");
resolutionGroup.orientation = "row";
resolutionGroup.add("statictext", undefined, "Resolution (DPI):");
var resolutionInput = resolutionGroup.add("edittext", undefined, "72");
resolutionInput.characters = 10;
// Compression quality
var qualityGroup = mainPanel.add("group");
qualityGroup.orientation = "row";
qualityGroup.add("statictext", undefined, "Quality (0-100):");
var qualityInput = qualityGroup.add("edittext", undefined, "75");
qualityInput.characters = 10;
// OK and Cancel buttons
var buttonGroup = dialog.add("group");
buttonGroup.orientation = "row";
var okButton = buttonGroup.add("button", undefined, "OK");
var cancelButton = buttonGroup.add("button", undefined, "Cancel");
// Folder browsing functionality
inputBrowseButton.onClick = function () {
var inputFolder = Folder.selectDialog("Select the input folder:");
if (inputFolder) {
inputFolderInput.text = inputFolder.fsName;
}
};
outputBrowseButton.onClick = function () {
var outputFolder = Folder.selectDialog("Select the output folder:");
if (outputFolder) {
outputFolderInput.text = outputFolder.fsName;
}
};
// OK button action
okButton.onClick = function () {
var inputFolder = Folder(inputFolderInput.text);
var outputFolder = Folder(outputFolderInput.text);
var maxSize = parseInt(maxSizeInput.text) || 1920;
var resolution = parseInt(resolutionInput.text) || 72;
var quality = parseInt(qualityInput.text) || 75;
// Ensure input/output folders are set
if (!inputFolder.exists || !outputFolder.exists) {
alert("Please select valid input and output folders.");
return;
}
dialog.close(1); // Close the dialog with "OK"
processFiles(inputFolder, outputFolder, maxSize, resolution, quality);
};
// Cancel button action
cancelButton.onClick = function () {
dialog.close(0); // Close the dialog with "Cancel"
};
// Show the dialog
if (dialog.show() == 1) {
// Continue processing if OK is pressed
} else {
// Do nothing if Cancel is pressed
}
// Main function to process the files
function processFiles(inputFolder, outputFolder, maxSize, resolution, quality) {
// Limit the input files, add or remove extensions as required
var fileList = inputFolder.getFiles(/\.(webp|tif|tiff|jpg|jpeg|psd|psb|png)$/i);
fileList.sort();
var savedDisplayDialogs = app.displayDialogs;
app.displayDialogs = DialogModes.NO;
// Set the file processing counter
var fileCounter = 0;
// Process the input files
for (var i = 0; i < fileList.length; i++) {
var doc = open(fileList[i]);
// If the doc isn't in RGB mode
if (activeDocument.mode !== DocumentMode.RGB) {
activeDocument.convertProfile("sRGB IEC61966-2.1", Intent.RELATIVECOLORIMETRIC, true, false);
activeDocument.changeMode(ChangeMode.RGB);
activeDocument.bitsPerChannel = BitsPerChannelType.EIGHT;
}
// Fit image to the specified max size
fitImage(maxSize, maxSize, resolution);
// Save as WebP and close
saveWebP(outputFolder, quality, true, true, true, true);
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
// Increment the file saving counter
fileCounter++;
}
// Function to resize image based on dimensions and resolution
function fitImage(fWidth, fHeight, resolution) {
if (activeDocument.height.value > activeDocument.width.value) {
activeDocument.resizeImage(null, UnitValue(fHeight, "px"), resolution, ResampleMethod.BICUBIC);
} else {
activeDocument.resizeImage(UnitValue(fWidth, "px"), null, resolution, ResampleMethod.BICUBIC);
}
}
app.displayDialogs = savedDisplayDialogs;
alert('Script completed!' + '\n' + fileCounter + ' files saved to:' + '\r' + outputFolder.fsName);
}
// Function to save as WebP
function saveWebP(outputFolder, quality, xmpData, exifData, psData, asCopy) {
var WebPDocName = activeDocument.name.replace(/\.[^\.]+$/, ''); // Remove file extension
var WebPSavePath = outputFolder + "/" + WebPDocName + ".webp"; // Define save path
var WebPFile = new File(WebPSavePath); // Create file object
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("compressionLossy")); // Lossy compression
descriptor2.putInteger(s2t("quality"), quality); // Set quality (0-100)
// Metadata options
descriptor2.putBoolean(s2t("includeXMPData"), xmpData);
descriptor2.putBoolean(s2t("includeEXIFData"), exifData);
descriptor2.putBoolean(s2t("includePsExtras"), psData);
// WebP format and save path
descriptor.putObject(s2t("as"), s2t("WebPFormat"), descriptor2);
descriptor.putPath(s2t("in"), WebPFile);
// Save As a Copy
descriptor.putBoolean(s2t("copy"), asCopy);
descriptor.putBoolean(s2t("lowerCase"), true);
// Execute save action
executeAction(s2t("save"), descriptor, DialogModes.NO);
}
}
... View more