• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Multiple WEBP Conversion Script with Recursion

Community Beginner ,
Feb 08, 2024 Feb 08, 2024

Copy link to clipboard

Copied

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_A_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
		}
		
	
	}());
	

 

TOPICS
Actions and scripting

Views

186

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Feb 09, 2024 Feb 09, 2024
quote

After some additional testing on this I can further confirm:

 

In the case of the PNGs, they all apear to be 'Indexed Color' profiles so could it be that the color profile selection in the script isn't working correctly?

 

@Rob35330516ixs7 


The issue appears to be that for Indexed Colour, a convert to profile command retains the Indexed Mode, but converts to the selected profile. I assumed that the mode would change too.

 

Indexed Colour isn't supported by WebP, so that would be the issue.

 

...

Votes

Translate

Translate
Adobe
Community Beginner ,
Feb 08, 2024 Feb 08, 2024

Copy link to clipboard

Copied

After some additional testing on this I can further confirm:

 

In the case of the PNGs, they all apear to be 'Indexed Color' profiles so could it be that the color profile selection in the script isn't working correctly?

 

When I try to open a couple of the small JPGs I get an error: "Could not complete your request because of a program error".

 

This may suggest in the case of the JPGs, the issue is not with the script.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Feb 08, 2024 Feb 08, 2024

Copy link to clipboard

Copied

Put the whole thing in a try/catch block to see if that helps find the problems.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 09, 2024 Feb 09, 2024

Copy link to clipboard

Copied

quote

After some additional testing on this I can further confirm:

 

In the case of the PNGs, they all apear to be 'Indexed Color' profiles so could it be that the color profile selection in the script isn't working correctly?

 

@Rob35330516ixs7 


The issue appears to be that for Indexed Colour, a convert to profile command retains the Indexed Mode, but converts to the selected profile. I assumed that the mode would change too.

 

Indexed Colour isn't supported by WebP, so that would be the issue.

 

Thanks for catching this, I'll need to update my code!

 

To fix, I would suggest changing from:

 

activeDocument.convertProfile("sRGB IEC61966-2.1", Intent.RELATIVECOLORIMETRIC, true, false);
activeDocument.bitsPerChannel = BitsPerChannelType.EIGHT;

 

To adding an extra line to explicitly set the colour mode after the profile conversion:

 

activeDocument.convertProfile("sRGB IEC61966-2.1", Intent.RELATIVECOLORIMETRIC, true, false);
activeDocument.changeMode(ChangeMode.RGB);
activeDocument.bitsPerChannel = BitsPerChannelType.EIGHT;

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Feb 13, 2024 Feb 13, 2024

Copy link to clipboard

Copied

Hi @Stephen_A_Marsh thank you for taking the time to look at this issue and apologies for posting in multiple places. I originally posted as a comment in the other post but when I looked, it seemed to have vanished so I started this post.

 

I've added in your extra line and this has fixed the issue with the Indexed Color PNGs.

 

Once again many thanks 👍

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 13, 2024 Feb 13, 2024

Copy link to clipboard

Copied

LATEST

@Rob35330516ixs7 – You're welcome! Thank you for 'breaking' the original script and highlighting this issue.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines