Welcome Dialog

Welcome to the Community!

We have a brand new look! Take a tour with us and explore the latest updates on Adobe Support Community.


Batch images with a script instead of actions

New Here ,
Oct 20, 2021 Oct 20, 2021

Copy link to clipboard

Copied

Hello, I'm running into an issue as I'm not too familiar with the scripting and batch processing side of Photoshop. But here's the dilemma, I have a script that adds a bunch of effects to an image that I'm interested in, and would like to batch process a couple thousand images with this script. Although, the batch process only lets me pick actions. I tried to create an action of the script working, but that didn't work. How do I batch images with a script?

TOPICS
Actions and scripting, Windows

Views

115

Likes

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

Adobe Community Professional , Oct 20, 2021 Oct 20, 2021
Easy way to include script in action is to place script in Presets > Scripts folder so you can see it in File > Scripts. WHile recording action just select script or even use Insert Menu Item to run script by action.

Likes

Translate

Translate
Adobe Community Professional ,
Oct 20, 2021 Oct 20, 2021

Copy link to clipboard

Copied

Look at the batch script that are available to you. Adobe Image Processor... and the better web download  Plug-in script Image processor Pro...  You can  include actions in their processing and those actions can use the scripts you have created. So you are batching your scripts.  It is also quit easy to create image file list with simple script functions  for your scripts to  batch process without needing to create a scriptUI dialog for the script.  I have created a few functions  myself for creating image file list.  I have create an example script you can look at here:

 

 

/* =======================================================================
// 2021  John J. McAssey (JJMack)
// ======================================================================= */
// This script is supplied as is. It is provided as freeware.
// The author accepts no liability for any problems arising from its use.
// enable double-clicking from Mac Finder or Windows Explorer
#target photoshop // this command only works in Photoshop CS2 and higher
// bring application forward for double-click events
app.bringToFront();
/////////////////////////////////////////////////////////////////////////
//                      SET-UP Global Variables                        //       
/////////////////////////////////////////////////////////////////////////
var scriptPath =  $.fileName.substr(0,$.fileName.lastIndexOf("/")+1);
var scriptName =  $.fileName.substr($.fileName.lastIndexOf("/")+1,$.fileName.lastIndexOf("."));
scriptName =  scriptName.substr(0,scriptName.lastIndexOf("."));
var scriptExt =  $.fileName.substr($.fileName.lastIndexOf("."));
//alert(scriptPath + scriptName + scriptExt);

// Initialize variables used in mainline	
var folderListCopy = new Array;
var fileListCopy = new Array;
var fileTypes = "";
var logData = "";

// Save the current preferences and Set Photoshop to use pixels and display no dialogs
var startRulerUnits = app.preferences.rulerUnits;
var startTypeUnits = app.preferences.typeUnits;
var startDisplayDialogs = app.displayDialogs;
app.displayDialogs = DialogModes.NO;
app.preferences.rulerUnits = Units.PIXELS;
app.preferences.typeUnits = TypeUnits.PIXELS;

try {
	startDate = (getDateTime());
	var time1 = Number(timeString());
	var processed = main(); // Select root folder and file types to process, crawl tree creating folderList and fileList then process file list
	if (processed!=undefined) { } //alert(processed + " Files Processed");
	if (logData!="") logInfo(timeStamp() + "\nFolders " + folderListCopy.length + " Files " + fileListCopy.length +  "\n" + fileTypes + "\n\n" + logData);  	
	var time2 = Number(timeString());
	endDate = (getDateTime());
	alert(startDate + " Start\n" 
//		+((time2-time1)/1000 )+" Seconds "
		+((time2-time1)/60000 ).toPrecision(2)+" Minutes " 
//		+((time2-time1)/3600000 ).toPrecision(1)+" Hours " 	
		+ "\n" + endDate + "  End" 
		+"\nProcessed " + folderListCopy.length + " Folders Selected " + fileListCopy.length + " Files Types Matching\n" 
		+ fileTypes + "\n"		
	);
}
catch(e) { alert(e + ': on line ' + e.line, 'Photoshop Error', true); }  
// Return the app preferences
app.preferences.rulerUnits = startRulerUnits;
app.preferences.typeUnits = startTypeUnits;
app.displayDialogs = startDisplayDialogs;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function main() { 
	//var files = buildFilelist ();											// Select image files from any folder till you stop and cancel				
	//var files = selectFile(true);											// Select Image files from a single folder
	//var files = selectsImagesFolder("x","x","jpg|jpe");						// Select a folder containg Image tree all jpeg image file types in the tree will be selected
	//var files = selectsImagesFolder(true,true,"jpg|jpeg");				// Select the root of the Image tree all jpeg image file types in the tree will be selected
	//var files = selectsImagesFolder(true,false);							// Select the root of the Image tree all image file types in the tree will be Selected
	//var files = selectsImagesFolder(true,true);							// Select the root of the Image tree and filter image file types to selected				
	//var files = selectsImagesFolder(false,false);							// Select a folder containg Image files all image file types in the folder will be Selected	
	//var files = selectsImagesFolder();										// Select a folder containg Image files all image file types in the folder will be Selected		
	//var files = selectsImagesFolder(false,true);							// Select a folder containg Image files and filter image file types to be Selected
	var files = selectsImagesFolder(true,true);								// Select image files
	if (files!=undefined) {
		fileListCopy = files;												// So boilerplate can see file processes
		for( var i=0; i < files.length;  i++) { processFile(files[i]); }	// Process Files	
		return  files.length;
	}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

function selectsImagesFolder (multi,selection,types) { // Build a file list of selected image file types in folder
	var folderList = new Array;
	var fileList = new Array;
	if (multi == true) {var theString = "Please select root folder"}							// Process Sub Folders   
	else {var theString = "Please select a folder"}; 											// Just a single folder  
    var rootFolder = Folder.selectDialog(theString, "");                    				    // Select root	
    if (rootFolder === null) { return};  														// Test if Cancel button returns null, then do nothing
	if (types!=undefined) typeList = types;														// filter these
	else {
		var typeList = "nef|cr3|cr2|crw|dcs|raf|arw|orf|dng|psd|tif|tiff|jpg|jpe|jpeg|png|bmp"; // Get file types
		if (selection == true) 	var typeList = prompt("Add or Remove file type to Process.",typeList);	// User modifies file type selection	
		if (typeList === "" || typeList === null ) { return};									// Test if Cancel button returns null, then do nothing
	}
	fileTypes = typeList;																		// Add Global for boiler plate	
	var matchString = String("/\\.(" + typeList + ")$/i");										// Add the rest of the regular expression	
	folderList.push(rootFolder);																// Start the Folder list at the root
	if (multi == true) getFolders(rootFolder,folderList);										// folderlist		
	getFilelist(folderList,matchString,fileList)												// fileList
	if (fileList=="") { return}; 																// Return if  no files selected
	function getFolders(pfolder,list) {															// Recursively crawl the tree  build the folder List
		var dirList = pfolder.getFiles();														// Get files and sub-folders
		for (var i = 0; i < dirList.length; i++) {
			if (dirList[i] instanceof File) { }													// Just process Folders
			else {
				list.push(dirList[i]);															// Add to folder list  
				getFolders(dirList[i],list);													// Add its sub-folders
			};
		}
	}	
	function getFilelist(folders,filter,list) {  
		for( var i=0; i < folders.length;  i++) { 												// Process folders
			var files = folders[i].getFiles(eval(filter));										// Select files
			for( var f=0; f < files.length;  f++) {list.push(files[f]);}						// Add files to selected fileList
		}
	} 
	folderListCopy = folderList;																// Add Global for boiler plate
	return  fileList;																			// Return files	
}

function buildFilelist () { // Build a file list of image files
	var buildList = new Array;
	var addfiles = selectFile(true);
	if (addfiles !== null ) {
		while (addfiles !== null ) {
			if (addfiles.length ==1) buildList.push(addfiles);
			else for( var i=0; i < addfiles.length;  i++) {buildList.push(addfiles[i]);}
			var addfiles = selectFile(true);
		}
	}
	return buildList;
}

function selectFile (multi) { // Select image files only
	if (multi == true) {var theString = "Please select files to be processed"}   
	else {var theString = "Please select a file"};   
	if ($.os.search(/windows/i) != -1) {var theFiles = File.openDialog (theString, '*.nef;*.cr3;*.cr2;*.crw;*.dcs;*.raf;*.arw;*.orf;*.dng;*.psd;*.psdt;*.tif;*.tiff;*.jpg;*.jpe;*.jpeg;*.png;*.bmp', multi)}   
	else {var theFiles = File.openDialog (theString, getFiles, multi)};   
	function getFiles (theFile) {  	////// filter files  for mac //////    
		if (theFile.name.match(/\.(nef|cr3|cr2|crw|dcs|raf|arw|orf|dng|psd|tif|tiff|jpg|jpe|jpeg|png|bmp)$/i) || theFile.constructor.name == "Folder") {  
			return true   
			};   
	};   
	return theFiles   
};	

function logInfo(Txt){ // Create write and open log file
    try {	
       var file = new File(Folder.desktop + "/" + scriptName + " Log.txt"); 
       file.open("w", "TEXT", "????"); 
       file.encoding = "UTF8";
       file.seek(0,2);   
       $.os.search(/windows/i)  != -1 ? file.lineFeed = 'windows'  : file.lineFeed = 'macintosh';
       file.writeln(Txt); 
       if (file.error) alert(file.error);
       file.close();
       file.execute(); 
    }
    catch(e) { alert(e + ': on line ' + e.line, 'Script Error', true); }
};   
 
function getDateTime() { // Function for returning current date and time
	var date = new Date();
	var dateTime = "";
	if ((date.getMonth() + 1) < 10) { dateTime += "0" + (date.getMonth() + 1) + "/"; }
	else { dateTime += (date.getMonth() + 1) + "/";}
	if (date.getDate() < 10) { dateTime += "0" + date.getDate() + "/"; } 
	else { dateTime += date.getDate() + "/"; }
	dateTime += date.getFullYear() + "_";
	if (date.getHours() < 10) {dateTime += "0" + date.getHours() + ":"; } 
	else { dateTime += date.getHours() + ":"; }
	if (date.getMinutes() < 10) { dateTime += "0" + date.getMinutes() + ":"; } 
	else { dateTime += date.getMinutes() + ":"; }
	if (date.getSeconds() < 10) { dateTime += "0" + date.getSeconds(); } 
	else { dateTime += date.getSeconds(); }
	return dateTime;
} 

function timeString () { // Function for returning raw time
  var now = new Date();
  return now.getTime()
};

function timeStamp(){

	// Get the time and format it
	var digital = new Date();
	var hours = digital.getHours();
	var minutes = digital.getMinutes();
	var seconds = digital.getSeconds();
	var amOrPm = "AM";
	if (hours > 11) amOrPm = "PM";
	if (hours > 12) hours = hours - 12;
	if (hours == 0) hours = 12;
	if (minutes <= 9) minutes = "0" + minutes;
	if (seconds <= 9) seconds = "0" + seconds;

	// Get the date and format it
	var date = new Date();
	var d  = date.getDate();
	var day = (d < 10) ? '0' + d : d;
	var m = date.getMonth() + 1;
	var month = (m < 10) ? '0' + m : m;
	var yy = date.getYear();
	var year = (yy < 1000) ? yy + 1900 : yy;
	
	// create a variable with the fully formatted the time and date
	// todaysDate = hours + ":" + minutes + ":" + seconds + " " + amOrPm + " - " + day + "/" + month + "/" + year;
	// todaysDate = hours + ":" + minutes + ":" + seconds + " " + amOrPm + " - " + month + "/" + day + "/" + year;

	MonthNames = new Array("January","February","March","April","May","June","July","August","September","October","November","December");

	//todaysDate = hours + ":" + minutes + ":" + seconds + " " + amOrPm + " " + MonthNames[date.getMonth()] + " " + date.getDate() + ", " + year;
	
	todaysDate =MonthNames[date.getMonth()] + " " + date.getDate() + ", " + year  +" " + hours + ":" + minutes + ":" + seconds + " " + amOrPm;

        return todaysDate;
}  

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//  Selected file are processed here
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function processFile(file) {  // Process Your files here
    // Here I just parse the  Files Into  Path Name and Extension and Log them 
	// var startDate Could be used for output File Name  suffix
	// var scriptName could also be useful
	var filePath =  String(file).substr(0,String(file).lastIndexOf("/")+1);
	var fileName =  String(file).substr(String(file).lastIndexOf("/")+1,String(file).lastIndexOf("."));
	fileName =  fileName.substr(0,fileName.lastIndexOf("."));
	var fileExt =  String(file).substr(String(file).lastIndexOf("."));
	
	logData = logData  + filePath + "\nName: " + fileName + "\nExt : " + fileExt + "\n\n";
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//   When last file is process the script will end
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

JJMack

Likes

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
New Here ,
Oct 20, 2021 Oct 20, 2021

Copy link to clipboard

Copied

Thanks so much!! I will give the plug-in a shot and see if I can figure out this script as well.

Likes

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
Adobe Community Professional ,
Oct 20, 2021 Oct 20, 2021

Copy link to clipboard

Copied

If you're not into scripting, you can still use a Batch Action.

 

Either install the script, then insert the script into the action... Or start recording the action,  browse to the script and wait for the script to finish, then stop the recording.

 

Downloading and Installing Adobe Scripts

Likes

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
Adobe Community Professional ,
Oct 20, 2021 Oct 20, 2021

Copy link to clipboard

Copied

My error I got threads mixed up

JJMack

Likes

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
Adobe Community Professional ,
Oct 20, 2021 Oct 20, 2021

Copy link to clipboard

Copied

Easy way to include script in action is to place script in Presets > Scripts folder so you can see it in File > Scripts. WHile recording action just select script or even use Insert Menu Item to run script by action.

Likes

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
New Here ,
Oct 21, 2021 Oct 21, 2021

Copy link to clipboard

Copied

This actually worked, once I moved the script to the folder, instead of using the plug-in it came with.

 

However, now I have a new issue. I've successfully managed to get the action to run the script, save the file with save as, and close the file aftewards. But, Photoshop is not opening the files in order. Each file is numbered 1 through 2200. Photoshop opens file 1, then 10, then 100, then 1000, and then decides to proceed with 1002, etc etc. The Batch Process is saving them as 0001, 0002, 0003, etc, which is what I wanted, because I thought Photoshop would open the files in order.

 

How do I force Photoshop to open the files in order and save them sequentially as intended?

Likes

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
Adobe Community Professional ,
Oct 21, 2021 Oct 21, 2021

Copy link to clipboard

Copied

Likes

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
New Here ,
Oct 21, 2021 Oct 21, 2021

Copy link to clipboard

Copied

I guess I should have Googled more before posting, but figured it out. Just had to bulk rename everything to have leading 00's infront so it would run in order.

 

But, everything is working as intended now! And now I have a 37-48hr long batch process ahead of me. Thanks everyone for the help and pointing me in the right direction!

Likes

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
Adobe Community Professional ,
Oct 21, 2021 Oct 21, 2021

Copy link to clipboard

Copied

Mark the answer that helped you the much as correct solution then 😉

Likes

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
Adobe Community Professional ,
Oct 21, 2021 Oct 21, 2021

Copy link to clipboard

Copied

LATEST

I have many version of Photoshop installed  copying scripts to all version presets would be a maintenance nightmare.  It is easier just to link Photoshop presets scripts folder to a common additional Photoshop script tree that you maintain for all versions of Photoshop you have installed.   Its a Pain to  use Photoshop menu File>Scripts>ScriptNameList  when you have a lot of Photoshop scripts install in Photoshop.  It takes forever and a day to scroll to the script you wan to use for Adobe only scrolls the list one line at a  time.  I run scripts from Windows File Explorer in Photoshop.  I needed  to add a option is my Photoshop psuserconfig.txt  to get rid of the nag Adobe message about running scripts form file explorer.

# Photoshop use WinTab Stylus 0 or use INK  Stylus 1
UseSystemStylus 0
# CC 2019 20.0.5 supress warning about running scripts.
WarnRunningScripts 0

 

JJMack

Likes

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