Copy link to clipboard
Copied
Hello,
I have a question about webp format in photoshop. I want to export many files at once in webp format in Photoshop but I don't find the webp format in photoshop options. Is it normal?
Best regards
WebP was introduced in Ps2022 as a native Save As (a Copy) option, not under Export As/Quick Export. You will either need to set up a batch action to save directly to WebP or to convert from PNG to WebP or use a custom script to save or convert to WebP.
In previous versions, there were 3rd party plugins from Google or other developers.
Update: A GUI version of the script here...
__________
Here is a batch script to save as WebP.
Features:
* Optionally run an action (edit the code to enable)
* Optionally ask to overwrite existing files (edit the code to enable)
* Set an input and output folder
* Set supported input file types (edit the code)
* Automatically converts non-RGB mode to sRGB space, 8 bpc
* RGB files automatically converted to 8 bpc
* Option to convert RGB mode to sRGB space (edit the code to enable)
* WebP lossy
...Copy link to clipboard
Copied
Copy link to clipboard
Copied
I amhaving a hard time understanding what the input and out put folder do ...so is the input folder is where it will grab all the files in that folder ?
By @Carlos Rendon
Yes!
Input = Source (open supported files from this folder)
Output = Destination (save as webp to this folder)
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Yes, it's possible using multiselect and shouldn't be too laborious.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
I'll look at it tomorrow when I have free time.
https://gist.github.com/MarshySwamp/8778d55f6fe5f18635fb4660dc485e58
Copy link to clipboard
Copied
Try this 1.3 version:
/*
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 - 12th January 2024: Replaced the input folder dialog with a file selection dialog
v1.3 - 10th February 2024: Added an explicit mode change to RGB
*/
#target photoshop
// Optionally run a specified action
//var actionName = "Molten Lead"; // Action to run, change as needed
//var actionSet = "Default Actions"; // Action set to run, change as needed
// 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...");
// Pass
} else {
// Set the input/source and output/destination variables
var selectFile = File.openDialog("Please select the file/s to save to WebP:", Multiselect = true);
var outputFolder = Folder.selectDialog("Please select the output/destination folder:");
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 < selectFile.length; i++) {
var doc = open(selectFile[i]);
// If the doc isn't in RGB mode
if (activeDocument.mode !== DocumentMode.RGB) {
// Convert to sRGB & 8 bpc
activeDocument.convertProfile("sRGB IEC61966-2.1", Intent.RELATIVECOLORIMETRIC, true, false);
activeDocument.changeMode(ChangeMode.RGB);
activeDocument.bitsPerChannel = BitsPerChannelType.EIGHT;
// Run the optional action
//app.doAction(actionName, actionSet);
// Fit image to 1920px
fitImage(1920, 1920);
// 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);
// Fit image to 1920px
fitImage(1920, 1920);
// Save as a copy and close
saveWebP("compressionLossy", 75, true, true, true, true);
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
// Increment the file saving counter
fileCounter++;
}
};
/* NEARESTNEIGHBOR | BILINEAR | BICUBIC | BICUBICSMOOTHER | BICUBICSHARPER | BICUBICAUTOMATIC */
function fitImage(fWidth, fHeight) {
if (activeDocument.height.value > activeDocument.width.value) {
activeDocument.resizeImage(null, UnitValue(fHeight, "px"), null, ResampleMethod.BICUBIC);
} else {
activeDocument.resizeImage(UnitValue(fWidth, "px"), null, null, ResampleMethod.BICUBIC);
}
}
app.displayDialogs = savedDisplayDialogs;
alert('Script completed!' + '\n' + fileCounter + ' files saved to:' + '\r' + outputFolder.fsName);
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
}
}
Copy link to clipboard
Copied
Hi @Stephen_A_Marsh,
How can we add a possibility to resize the image to ex. 1400x1400px centered, while maintaining canvas at 2100x2100px, still bulk to webp?
Thanks in advance
Copy link to clipboard
Copied
Simply change the input where it says resize to your need. But what your asking sound confusing. You want to resize to 1400x1400 but keep it at 2100x2100
Copy link to clipboard
Copied
I want to resize the input to to be resized to 1400x1400px and centered and canvas at 2100x2100px; so that the output will be a 2100x2100px webP file.
Copy link to clipboard
Copied
But that isnt simply an export and resize. You would need think about what happens with the background, what color does it need to get.
You could simply add code in this script or call a cusro action from this script
Copy link to clipboard
Copied
I want to resize the input to to be resized to 1400x1400px and centered and canvas at 2100x2100px; so that the output will be a 2100x2100px webP file.
By @mxdsP
* Will the input files always be 1:1 aspect ratio? Or do you need to force this?
* Will the input files always be flattened with only a special flat Background layer? If so, what colour should the background extension be? Or will the input files always have floating transparent layers? When resized to 2100px what should happen with the transparent background? Or will there be a mixture of both layered and flattened input files? Should they be treated the same or differently?
Copy link to clipboard
Copied
I think it would be better he makes an action for the file which gets called from the script. That easier and very customizable. You could call allkinds of different actions before doing the export.
Copy link to clipboard
Copied
I think it would be better he makes an action for the file which gets called from the script. That easier and very customizable. You could call allkinds of different actions before doing the export.
By @schroef
I agree that this is often more user friendly and gives control back to the user who may not know scripting. That is why I put in placeholder code to run an action that can be uncommented and have the action set and action name changed to suit.
Copy link to clipboard
Copied
Sorry, I guess I missed that. But our thoughts are on the same level 😉
Copy link to clipboard
Copied
Sorry, I guess I missed that. But our thoughts are on the same level 😉
By @schroef
They are indeed! 👍
Copy link to clipboard
Copied
Background will always be transparent, both input and output.
What I want to achieve is input files is constricted to the guide either by max-height of 1800px or max-width of 1400px, without breaking the aspect ratio of the input file.
Canvas here is h2210px w2210px
In this example the image is originally w776px h1114px, then it should be resized to either h1800px or w1400px, in this case h1800px and w1249px.
Copy link to clipboard
Copied
@mxdsP – Automating this to the inner set of guides isn't easy or something I would try to do (unless you can find or make a script to do so or the image has an alpha channel or path created from the inner guides). If there were only 4 guides then it would be "easier".
I think a better approach would be to trim to transparency, then once the subject is "close-cropped" I would run Automate > Fit Image to W1400px / H1800px and then adjust the canvas size afterwards to 2100px square from the centre. This would make all image content consistent and centred.
In your example, you are upscaling the layer content, which also has a repeating pattern showing a visually unappealing moiré/aliasing effect.
P.S. Your sample shows 3 layers and a Background image layer, I presume that you would not export the Background and that all other layers would be exported one at a time with no other layers visible. I'm also presuming that there could be any number of layers present in each file. So the script is no longer just a batch save to WebP – it's now a batch save layers to WebP.
Copy link to clipboard
Copied
@Stephen_A_Marsh, thank you for this, I think your approach is smarter than my overthinking, haha.
I would still wanna just use your script approach, from an input folder, I just really wanted to automate (or at least semi-automate) the process of image scaling with margins and webP output.
Any way to automate such process in PS, because I need to go through 10k+ images, thats why I wanted to try and find a bulk solution and I ended in this tread to begin with.
Again really appreciate your help!
Copy link to clipboard
Copied
@mxdsP - Yes, I can help you. This will require different code to process layers to your requirements.
What file types? Just transparent layered PSD input?
Is this 10K of images in a single top-level input folder?
Or are there images in sub-folders under the top-level folder? If so, do you wish to process one sub-folder manually at a time, or just select the top-level folder and the script will then automatically process all sub-folders?
Where will the WebP files be saved? Back into the source folders next to the input files? Into a new WebP sub-folder in the source folders? To a brand new top-level folder in another location? Something else?
Copy link to clipboard
Copied
@Stephen_A_Marsh - thank you!
Input images are a blend of jpeg | png | webp.
Images are in sub-folders under top-level folder so if this can be handled, that would be very cool.
Output file should be webP transparant with inner guide at w1300px h1800px and upscaled/downscaled from input files.
Files should be saved back in the source folder and have suffix ex. 2210x2210.
Copy link to clipboard
Copied
@mxdsP – So how will the JPEG files be handled, they will not have transparency. Are they just resized to the canvas fit of 1400/1800 pixels - then add a transparent square canvas extension to 2100px?
What was going on with your untitled 3 layer document example? So you don't actually have any layered files? The code will be different to process a multi-layer file vs. a single-layer file, so I need to understand what is really required. I don't want to waste time and effort trying to hit a moving target.
Can you provide a small quantity of before/after images in different source file formats and portrait and landscape orientation to make it crystal clear? You can private message me if you don't want to make these public.
Copy link to clipboard
Copied
@Stephen_A_Marsh - For simplicity just go with pngs only as input files, because thats like 95% is png.
That was just 3 images of the same product series. So file is single-layer, sorry for the confusion.
File examples here, webP files are the goal.
https://we.tl/t-DSlawD0NVU
Copy link to clipboard
Copied
The following script can be recorded into an action using File > Scripts > Browse... (otherwise install the action in the Presets/Scripts directory).
Next use File > Automate > Batch and select the action set and action.
/*
2120px WebP for Automate Batch.jsx
v1.0 - 9th March 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/export-many-files-at-once-in-webp-format-photoshop/td-p/13604411/page/3
Use Automate > Batch to process an input folder + include all subfolders, set the Destination options to NONE as the script will handle the output
*/
// 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...");
// Pass
} else {
// Doc and path save variables
var WebPDocName = activeDocument.name.replace(/\.[^\.]+$/, ''); // Remove file extension
var WebPSavePath = activeDocument.path.fsName + "/" + WebPDocName + "-2210x2210.webp"; // Change path as needed
var WebPFile = new File(WebPSavePath); // Create the file object
// If the doc isn't in RGB mode and isn't flattened
if (activeDocument.mode !== DocumentMode.RGB && !activeDocument.activeLayer.isBackgroundLayer && activeDocument.layers.length == 1) {
// Convert to sRGB & 8 bpc
activeDocument.convertProfile("sRGB IEC61966-2.1", Intent.RELATIVECOLORIMETRIC, true, false);
// 10th February 2024, ensure that the doc mode is RGB
activeDocument.changeMode(ChangeMode.RGB);
activeDocument.bitsPerChannel = BitsPerChannelType.EIGHT;
// Call the main function
processTo2120px();
// Save as a copy and close
saveWebP("compressionLossy", 75, true, true, true, true, true);
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
// If the doc is in RGB mode and isn't flattened
} else if (!activeDocument.activeLayer.isBackgroundLayer && activeDocument.layers.length == 1) {
// Convert to sRGB & 8 bpc
activeDocument.convertProfile("sRGB IEC61966-2.1", Intent.RELATIVECOLORIMETRIC, true, false);
activeDocument.bitsPerChannel = BitsPerChannelType.EIGHT;
// Call the main function
processTo2120px();
// Save as a copy and close
saveWebP("compressionLossy", 75, true, true, true, true, true);
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
// Close the doc if it is flattened with no transparency
} else {
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}
}
// End of script
//app.beep();
function processTo2120px() {
// Trim to transparency
app.activeDocument.trim(TrimType.TRANSPARENT);
// Fit image
fitImage(1400, 1800);
app.activeDocument.resizeCanvas(2120, 2120, AnchorPosition.MIDDLECENTER);
}
function fitImage(fWidth, fHeight) {
/* NEARESTNEIGHBOR | BILINEAR | BICUBIC | BICUBICSMOOTHER | BICUBICSHARPER | BICUBICAUTOMATIC */
if (activeDocument.height.value > activeDocument.width.value) {
activeDocument.resizeImage(null, UnitValue(fHeight, "px"), null, ResampleMethod.BICUBIC);
} else {
activeDocument.resizeImage(UnitValue(fWidth, "px"), null, null, ResampleMethod.BICUBIC);
}
}
function saveWebP(compType, compValue, xmpData, exifData, psData, asCopy, embedProfiles) {
/*
v1.1 - 12th March 2023, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/saving-webp-image-by-script/td-p/13642577
*/
/*
// 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);
// ICC Profile
descriptor.putBoolean( s2t( "embedProfiles" ), embedProfiles );
// Execute the save
executeAction(s2t("save"), descriptor, DialogModes.NO); // Change NO to ALL for dialog
}
Copy link to clipboard
Copied
@Stephen_A_Marsh - Okay, I think I am missing something. I can't seem to figure out where to add the action to the Batch.