BatchUpdateSmartObjects.jsx - I'm in over my head... help ?

Community Beginner ,
Mar 19, 2021 Mar 19, 2021

Copy link to clipboard

Copied

Hi everyone !

 

I'm ultra new to scripts in Photoshop but I've been trying to do something I apparently can't do without them :

 

I currently have two folders with images I'm trying to merge. One with 535,000 images in PNG format with a unique title (eg: QR50000000001.png, QR50000000002.png, ...). The other folder has 535,000 images in TIFF format with a matching unique title (eg: banner50000000001.tif, banner50000000002.png, ...).

What I need to do is align the QR files with the Banner files, merge them, and save them with the title of the original QR image.

 

My "banners" look like this and are 625px / 600px : 

 

Sébastien15A7_5-1616173091493.png

(I masked some private info)

 

My QR images look like this and are 295px / 295px:

Sébastien15A7_7-1616173355432.png

(Same, sloppy censoring, sorry)

 

The final result should look like this.

Sébastien15A7_8-1616173475593.png

 

 

Having done some research, I've found @JJMack's amazing response to a similar type of question and

have done quite a lot of attempts to try and make it work.

 

Until now, I've been able to adapt the "Crossroads2500" template to match my final design.

 

Sébastien15A7_0-1616171517697.png

 

With this design, I've been able to successfully run the script BatchUpdateSmartObjects.jsx using the original files JJMack uploads in his example.

 

 

/* ==========================================================
// 2010  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.

// Image files and Template  objects should have the same orientation close matching Aspect Ratios same
// ratio is even better.  This script can try to edit smart objects and fit any size image the
// best as it can and even try to handle orientation miss matches.

/* Help Category note tag menu can be used to place script in automate menu
<javascriptresource>
<about>$$$/JavaScripts/BatchUpdateSmartObjects/About=JJMack's Batch Update Smart Image MockUp.^r^rCopyright 2019 Mouseprints.^r^rBatch Update Top Layers Smart Object</about>
<category>JJMack's Collaga Script</category>
</javascriptresource>
*/

// 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 Preferences	//       
//////////////////////////////////
//@include "PCTpreferences.jsx"

var gVersion = 1.0;

// a global variable for the title of the dialog
// this string will also be used for the preferences file I write to disk
// Photoshop Install Directory/Presets/Image Processor/Image Processor.xml for example

var gScriptName = "BSOCollage";

// remember the dialog modes
var saveDialogMode = app.displayDialogs;
app.displayDialogs = DialogModes.NO;

try {
	// make sure they are running Photoshop CS2
	CheckVersion();

}
// Lot's of things can go wrong, Give a generic alert and see if they want the details
catch(e) {
	if ( confirm("Sorry, something major happened and I can't continue! Would you like to see more info?" ) ) {
		alert(e + ': on line ' + e.line, 'Photoshop Error', true); 
	}
}


// Save the current preferences
var startRulerUnits = app.preferences.rulerUnits;
var startTypeUnits = app.preferences.typeUnits;
var startDisplayDialogs = app.displayDialogs;

// Set Photoshop to use pixels and display no dialogs
app.displayDialogs = DialogModes.NO;
app.preferences.rulerUnits = Units.PIXELS;
app.preferences.typeUnits = TypeUnits.PIXELS;
	
// Set the script location

var scriptLocation = findScript() + "0";

// Stuff I don't know much about
var strButtonSelect = localize("$$$/JavaScripts/ExportLayersToFiles/Select=Select...");
var strButtonBrowse = localize("$$$/JavaScripts/ExportLayersToFiles/Browse=Browse...");
var strAlertSpecifyTemplateFile = localize("$$$/JavaScripts/ExportLayersToFiles/SpecifyTemplateFile=Please specify a template file.");
var strAlertTemplateFileNotExist = localize("$$$/JavaScripts/ExportLayersToFiles/TemplateFileDoesNotExist=Template file does not exist.");
var strAlertSpecifyInputFolder = localize("$$$/JavaScripts/ExportLayersToFiles/SpecifyInputFolder=Please specify an input folder.");
var strAlertInputFolderNotExist = localize("$$$/JavaScripts/ExportLayersToFiles/InputFolderDoesNotExist=Input folder does not exist.");
var strAlertSpecifyDestination = localize("$$$/JavaScripts/ExportLayersToFiles/SpecifyDestination=Please specify an output folder.");
var strAlertDestinationNotExist = localize("$$$/JavaScripts/ExportLayersToFiles/DestionationDoesNotExist=Output folder does not exist.");

var exportInfo = new Object();
initExportInfo(exportInfo);										// ??????
	
// define the dialog	
// [left, top, right, bottom]
function createDialog(){

	// Create an empty dialog window near the upper left of the screen
	var dlg = new Window('dialog', 'Simple Smart Object Template');
	dlg.frameLocation = [78, 100];

	// Add a panel to hold title and 'message text' strings
	dlg.msgPn0 = dlg.add('panel', undefined, 'Simple MockUp Template File');
	dlg.msgPn0.orientation = "column";
	dlg.msgPn0.alignChildren = 'Right';
	// Add a panel to hold title and 'message text' strings
	dlg.msgPn0.TemplateFile = dlg.msgPn0.add('group');
	dlg.msgPn0.TemplateFile.orientation = "row";
	dlg.msgPn0.etTemplateFile = dlg.msgPn0.add("edittext", undefined, exportInfo.destination.toString());
	dlg.msgPn0.etTemplateFile.preferredSize.width = 550;
	dlg.msgPn0.etTemplateFile.helpTip = "Choose a collage template to populate.";

	dlg.msgPn0.btnSelect = dlg.msgPn0.add("button", undefined, strButtonSelect);
	dlg.msgPn0.btnSelect.helpTip = "Select a collage template to populate.";
	dlg.msgPn0.btnSelect.onClick = function() {
		var dir = Folder(dlg.msgPn0.etTemplateFile.text.substr(0, dlg.msgPn0.etTemplateFile.text.lastIndexOf("\\")+1));
		if (!dir.exists) var dir =  Folder(templateFolder);

		dlg.selTemplateFile = dir.openDlg(dlg.msgPn0.etTemplateFile.text , "Select:*.psd;*.psdt;*.psb");
		if ( dlg.selTemplateFile != null ) {
	        dlg.msgPn0.etTemplateFile.text = dlg.selTemplateFile.fsName;
	    }
		//dlg.msgPn0.defaultElement.active = true;
	}

	// Add a panel to hold title and 'message text' strings
	dlg.msgPn2 = dlg.add('panel', undefined, 'Objects Collection Folder');
	dlg.msgPn2.orientation = "column";
	dlg.msgPn2.alignChildren = 'Right';

	dlg.msgPn2.InputFolder = dlg.msgPn2.add('group');
	dlg.msgPn2.InputFolder.orientation = "row";
	dlg.msgPn2.etInputFolder = dlg.msgPn2.add("edittext", undefined, exportInfo.destination.toString());
	dlg.msgPn2.etInputFolder.preferredSize.width = 550;
	dlg.msgPn2.etInputFolder.helpTip = "Choose a folder of images to process.";

	dlg.msgPn2.btnBrowse = dlg.msgPn2.add("button", undefined, strButtonBrowse);
	dlg.msgPn2.btnBrowse.helpTip = "Select the Collection of objects folders to process.";
	dlg.msgPn2.btnBrowse.onClick = function() {
		var defaultFolder = dlg.msgPn2.etInputFolder.text;
		var testFolder = new Folder(dlg.msgPn2.etInputFolder.text);
		if (!testFolder.exists) {
//			defaultFolder = "~";
			defaultFolder = imagePath;
		}
		// var selFolder = Folder.selectDialog(dlg.msgPn2.etInputFolder.text, defaultFolder);
		dlg.selInputFolder = Folder.selectDialog(dlg.msgPn2.etInputFolder.text, defaultFolder);
		if ( dlg.selInputFolder != null ) {
	        dlg.msgPn2.etInputFolder.text = dlg.selInputFolder.fsName;
	    }
		//dlg.msgPn2.defaultElement.active = true;
	}

	// Add a panel to hold title and 'message text' strings
	dlg.msgPn3 = dlg.add('panel', undefined, 'Output Folder');
	dlg.msgPn3.orientation = "column";
	dlg.msgPn3.alignChildren = 'Right';

	dlg.msgPn3.Destination = dlg.msgPn3.add('group');
	dlg.msgPn3.Destination.orientation = "row";
	dlg.msgPn3.etDestination = dlg.msgPn3.add("edittext", undefined, exportInfo.destination.toString());
	dlg.msgPn3.etDestination.preferredSize.width = 550;
	dlg.msgPn3.etDestination.helpTip = "Choose a folder to export your collages to.";

	dlg.msgPn3.btnBrowse = dlg.msgPn3.add("button", undefined, strButtonBrowse);
	dlg.msgPn3.btnBrowse.helpTip = "Select a folder to export your collages to.";
	dlg.msgPn3.btnBrowse.onClick = function() {
		var defaultFolder = dlg.msgPn3.etDestination.text;
		var testFolder = new Folder(dlg.msgPn3.etDestination.text);
		if (!testFolder.exists) {
			defaultFolder = "~";
		}
		dlg.selOutputFolder = Folder.selectDialog(dlg.msgPn3.etDestination.text, defaultFolder);
		if ( dlg.selOutputFolder != null ) {
	        dlg.msgPn3.etDestination.text = dlg.selOutputFolder.fsName;
	    }
		//dlg.msgPn3.defaultElement.active = true;
	}
	
	// Add a panel to hold title and 'message text' strings
	dlg.msgPnl = dlg.add('panel', undefined, 'Options');
	dlg.msgPnl.orientation = "column";
	dlg.msgPnl.alignChildren = 'right';

	dlg.msgPnl.EditImage = dlg.msgPnl.add('group');
	dlg.msgPnl.EditImage.orientation = "row";
	dlg.msgPnl.EditImage.alignment='left';
	dlg.msgPnl.EditImage.st = dlg.msgPnl.EditImage.add('checkbox', undefined, 'Edit Smart Object');
	dlg.msgPnl.EditImage.helpTip = "Edit Smart Object insead of replace content";

	dlg.msgPnl.RotateForFit = dlg.msgPnl.add('group');
	dlg.msgPnl.RotateForFit.orientation = "row";
	dlg.msgPnl.RotateForFit.alignment='left';
	dlg.msgPnl.RotateForFit.st = dlg.msgPnl.RotateForFit.add('checkbox', undefined, 'Rotate For Best Fit');
	dlg.msgPnl.RotateForFit.helpTip = "Rotate For Best Fit.";
	
	dlg.msgPnl.FitImage = dlg.msgPnl.add('group');
	dlg.msgPnl.FitImage.orientation = "row";
	dlg.msgPnl.FitImage.alignment='left';
	dlg.msgPnl.FitImage.st = dlg.msgPnl.FitImage.add('checkbox', undefined, 'Fit Image');
	dlg.msgPnl.FitImage.helpTip = "Fit Image not Fill Area.";

	dlg.msgPnl.SavePSDfile = dlg.msgPnl.add('group');
	dlg.msgPnl.SavePSDfile.orientation = "row";
	dlg.msgPnl.SavePSDfile.alignment='left';
	dlg.msgPnl.SavePSDfile.st = dlg.msgPnl.SavePSDfile.add('checkbox', undefined, 'Save PSD file');
	dlg.msgPnl.SavePSDfile.helpTip = "Save a layered PSD file as well.";
	
	// Add a panel with buttons to test parameters and
	dlg.buttonPanel = dlg.add('panel', undefined);
	dlg.buttonPanel.orientation = "row";
	dlg.buttonPanel.cancelBtn = dlg.buttonPanel.add ('button', undefined,'Cancel');
	dlg.buttonPanel.helpBtn = dlg.buttonPanel.add ('button', undefined,'Help');
	dlg.buttonPanel.runBtn = dlg.buttonPanel.add ('button', undefined,'Create Mockup Collages');

	return dlg;
	}

	var params = new Array();
	params[''] = "";
	params['InputFolder'] = "";
	params['OutputFolder'] = "";
	
	LoadParamsFromDisk( GetDefaultParamsFile(), params );

        function initializeDialog (BSOCollage){
		with(BSOCollage) {

		msgPn0.etTemplateFile.text = params['TemplateFile'];
		msgPn2.etInputFolder.text = params['InputFolder'];
		msgPn3.etDestination.text = params['OutputFolder'];

		// Collage
		// checking for valid settings
		buttonPanel.runBtn.onClick = function() {

			// check if the template setting is proper
			var tmpltfld = BSOCollage.msgPn0.etTemplateFile.text;
			if (tmpltfld.length == 0) {
				alert(strAlertSpecifyTemplateFile);
				return;
			}
			var testFile = new File(tmpltfld);
			if (!testFile.exists) {
				alert(strAlertTemplateFileNotExist);
				return;
			}

			var inptfld = BSOCollage.msgPn2.etInputFolder.text;
			if (inptfld.length == 0) {
				alert(strAlertSpecifyInputFolder);
				return;
			}
			var testFolder = new Folder(inptfld);
			if (!testFolder.exists) {
				alert(strAlertInputFolderNotExist);
				return;
			}

			// check if the output folder setting is proper
			var destination = BSOCollage.msgPn3.etDestination.text;
			if (destination.length == 0) {
				alert(strAlertSpecifyDestination);
				return;
			}
			var testFolder = new Folder(destination);
			if (!testFolder.exists) {
				alert(strAlertDestinationNotExist);
				return;
			}

			// See if the input folder and the output folder are the same
			if (BSOCollage.msgPn3.etDestination.text == BSOCollage.msgPn2.etInputFolder.text) {
				var result = confirm("Are you sure you want your output folder to be the same as your input folder");
				if (result) {
				} else {
					return;
				}
			}

  	close( 1 ); // Close dialog window and process
	}

	buttonPanel.helpBtn.onClick = function() {help();}

	buttonPanel.cancelBtn.onClick = function() {close( 2 );}
	}
} // end createDialog

function runDialog(BSOCollage){
	// Warn the user if they have an open document and exit the script with return
	//if (documents.length > 0){
	//	alert ("This script requires that there are no open documents to run.");
	//return;
	//}		
	BSOCollage.onShow = function() {
		var ww = BSOCollage.bounds.width;  
		var hh = BSOCollage.bounds.height;  
		BSOCollage.bounds.x  = 78;  
		BSOCollage.bounds.y  = 100;  
		BSOCollage.bounds.width  = ww;  
		BSOCollage.bounds.height  = hh;  
		}
	return BSOCollage.show()
}

//=====================Start=====================================================
	
var BSOCollage = createDialog()	
initializeDialog(BSOCollage)

if (runDialog(BSOCollage) == 1){
	// transfer values from the dialog to my internal params
	params['TemplateFile'] = BSOCollage.msgPn0.etTemplateFile.text;
	params['InputFolder'] = BSOCollage.msgPn2.etInputFolder.text;
	params['OutputFolder'] = BSOCollage.msgPn3.etDestination.text;
	// Save the params from the above
	SaveParamsToDisk( GetDefaultParamsFile(), params );
	
	// Gets the template file from the UI
	var templateFile = BSOCollage.msgPn0.etTemplateFile.text;
	//alert(templateFile);

	// Gets the input folder from the UI
	var inputFolder = BSOCollage.msgPn2.etInputFolder.text;
	//alert(inputFolder);
	var inputFolder = new Folder(inputFolder);

	// Gets the output folder from the UI
	var outputFolder = BSOCollage.msgPn3.etDestination.text;
	//alert(outputFolder);
	var outputFolder = new Folder(outputFolder);

	//alert('Template="' + templateFile + '"\nImages from "' + inputFolder + '"\nSaved to "' + outputFolder +'"');
	startDate = (getDateTime());
	var time1 = Number(timeString());	
	open(File(templateFile));
	// Isolate Tenplate Name
	var templateName =  decodeURI(templateFile).replace(/\.[^\.]+$/, '');	// strip the extension off
	var templateName =  templateName.substr(templateName.lastIndexOf("\\")+1);	
	
    app.activeDocument.suspendHistory('BatchUpdateSmartObject','main(templateName)');
	
	activeDocument.close(SaveOptions.DONOTSAVECHANGES);							// Close No Save
	if (countSame) { 
		if (replaceCount) {
			var time2 = Number(timeString());
			endDate = (getDateTime());
			alert(startDate + " Start\n" 
			+ "Processed " + replaceCount + " files\n"
			//+ ((time2-time1)/1000 )+" Seconds "
			+((time2-time1)/60000 ).toPrecision(2)+" Minutes " 
			//+((time2-time1)/3600000 ).toPrecision(1)+" Hours " 				
			+ endDate + "  End" 
			);    
		}	
		else alert("No files found");
	}
} // end if (runDialog(BSOCollage) == 1)

// Return the app preferences
app.preferences.rulerUnits = startRulerUnits;
app.preferences.typeUnits = startTypeUnits;
app.displayDialogs = saveDialogMode;

//////////////////////////////////////////////////////////////////////////////////
//				The end						//
//////////////////////////////////////////////////////////////////////////////////
function main(templateName){
	//var templateName = activeDocument.name.replace(/\.[^\.]+$/, '');
	try {    
		var myDocument = app.activeDocument;    
	    var layers = myDocument.layers;	
		var theLayer = layers[0];    
 		if (theLayer.kind != "LayerKind.SMARTOBJECT") { alert(" Top layer is not a smart object") }   
		else {    
		    // add support for more tha one smart object layer
			//Count top smart obj
			var objCount = 0;
			i=0 
			var theLayers = new Array();
			while ( layers[i].kind == "LayerKind.SMARTOBJECT" ) { theLayers.push(layers[i]);objCount++ ; i++;}
			//alert("objCount " + objCount);
			// test the input folders exists
			foundFolders=true; notFound = "Required Folders missing\n";
			var objFolders = new Array();
			for (var i = 0; i < objCount; i++) {  
				objFolders.push(new Folder(inputFolder + "/obj" + i));
			    if (!objFolders[i].exists) {
					notFound = notFound + objFolders[i] + "\n";
					foundFolders=false;
				}
			}
			if (!foundFolders) alert(notFound);
			else {
				var rplFiles = new Array();
				if (!BSOCollage.msgPnl.EditImage.st.value) for (var i = 0; i < objCount; i++) {  rplFiles[i] = objFolders[i].getFiles(/\.(psd|tif|jpg|jpe|png)$/i); }	// gets file list
				else for (var i = 0; i < objCount; i++) {  rplFiles[i] = objFolders[i].getFiles(/\.(nef|cr3|cr2|crw|dcs|raf|arw|orf|dng|psd|tif|jpg|jpe|png)$/i); }	// gets file list
				replaceCount=rplFiles[0].length;
				//alert(replaceCount)
				countSame=true;
				for (var i = 0; i < objCount; i++) { if (rplFiles[i].length!=replaceCount) countSame=false;} // test all flist are the same lengt			
						
				if (countSame){
					for (var r = 0; r < replaceCount; r++) {   			// or replacement count 
						for (var o = 0; o < objCount; o++) {			// for objCount
							//The Layer and the file
							if (BSOCollage.msgPnl.EditImage.st.value) { 
								if (objectIsPsObject(theLayers[o])) theLayer = editContents(rplFiles[o][r], theLayers[o], BSOCollage.msgPnl.RotateForFit.st.value, BSOCollage.msgPnl.FitImage.st.value); 
								else {
									alert (theLayers[o] + " Object is not safe to edit");
									return;
								}	
							}							
							else theLayer = replaceContents(rplFiles[o][r], theLayers[o]); 		
						}
						var theNewName = rplFiles[0][r].name.match(/(.*)\.[^\.]+$/)[1]; 
						outputFile = outputFolder + "/" + theNewName +" " + templateName ;	// Construct full output file path
						SaveAsJPEG( outputFile , 10 );
						if (BSOCollage.msgPnl.SavePSDfile.st.value) SaveAsPSD( outputFile, true ); 						
					}
				}
				else alert("Replacemen object counts are not the same " + replaceCount);
			}
		}
	}
	catch(e) { alert(e + ': on line ' + e.line, 'Photoshop Error', true); }    	
	return;
}
//////////////////////////////////////////////////////////////////////////////////
//			Helper Functions					//
//////////////////////////////////////////////////////////////////////////////////

function replaceContents(newFile, theSO) {    
    try {    
		var lyrVis = theSO.visible; 
        app.activeDocument.activeLayer = theSO;    
        var idplacedLayerReplaceContents = stringIDToTypeID("placedLayerReplaceContents");    
        var desc3 = new ActionDescriptor();    
        var idnull = charIDToTypeID("null");    
        desc3.putPath(idnull, new File(newFile));    
        var idPgNm = charIDToTypeID("PgNm");    
        desc3.putInteger(idPgNm, 1);    
        executeAction(idplacedLayerReplaceContents, desc3, DialogModes.NO); 
		theSO.visible =	lyrVis; 
        return app.activeDocument.activeLayer    
        }     
    catch(e) { alert(e + "\nFile " + newFile, 'replaceContents', true); }
}    

function objectIsPsObject(SOlayer) {
	//Thanks to r-bin
	var ext = smartobject_file_ext(SOlayer);  
    var rc = true;
	switch (ext)  
		{  
		case "nef":  
		case "cr3":  
		case "cr2": 		
		case "crw":  
		case "raf":  
		case "orf":  
		case "mrw":  
		case "dcr":  
		case "mos":  
		case "raw":  
		case "pef":  
		case "srf":  
		case "dng":  
		case "x3f":  
		case "erf":  
		case "sr2":  
		case "kdc":  
		case "mfw":  
		case "mef":  
		case "arw":  
		case "nrw":  
		case "rw2":  
		case "rwl":  
		case "iiq":  
		case "3fr":  
		case "fff":  
		case "srw":  
		case "ai":
		case "svg":
		case "pdf":
		case "esp":
			rc = false;	
			break;  
		case "error":  
			rc = false;
			break;         
  		default:  
			rc = true;
			break;  
    }  
	return rc;
}
  
function smartobject_file_ext(layer) {  
    try {         
        var r = new ActionReference();     
        r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("smartObject"));  
        r.putIdentifier(stringIDToTypeID("layer"), layer.id);  
        var name = executeActionGet(r).getObjectValue(stringIDToTypeID("smartObject")).getString(stringIDToTypeID("fileReference"));         
         
        var n = name.lastIndexOf(".");  
        if (n < 0) return "";  
     
        return name.substr(n+1).toLowerCase();  
        }  
    catch (e) { return "error"; }  
}    
	
function editContents(newFile, theSO, rotateForBestFit, fitImage) {    
    try {    
		var lyrVis = theSO.visible; 
        app.activeDocument.activeLayer = theSO;  
		var smartObject = openSmartObject (theSO);			// open smart object;
		smartObject.flatten()	
		smartObject.activeLayer.isBackgroundLayer=0;		// Make it a normal Layer
		smartObject.selection.selectAll();
		smartObject.selection.clear();						// One clear did not work
		var objWidth=smartObject.width.value;
		var objHeight=smartObject.height.value;	   
		open(File(newFile));								// open it into a document
		var layers = activeDocument.layers;
		activeDocument.activeLayer = layers[layers.length-1]; // Target Bottom Layer
		activeDocument.activeLayer.isBackgroundLayer=0; 	// Make it a normal Layer
		try {
			var objFile= app.activeDocument;				// image document
			if (rotateForBestFit) {
				if (objFile.width.value<objFile.height.value&&objWidth>objHeight ) { objFile.rotateCanvas(-90.0);  } // Rotate portraits
				if (objFile.height.value<objFile.width.value&&objHeight>objWidth ) { objFile.rotateCanvas(-90.0);  } // Rotate landscapes
				}
			if (!fitImage) {		
				if (objFile.width.value/objFile.height.value > objWidth/objHeight) { objFile.resizeImage(null, objHeight, null, ResampleMethod.BICUBIC); } // wider
				else {objFile.resizeImage(objWidth, null, null, ResampleMethod.BICUBIC);} // same aspect ratio or taller
			}
			else{
				if (objFile.width.value/objFile.height.value > objWidth/objHeight) {objFile.resizeImage(objWidth, null, null, ResampleMethod.BICUBIC);  }  // wider
				else {objFile.resizeImage(null, objHeight, null, ResampleMethod.BICUBIC);}
			}
			try {objFile.resizeCanvas(objWidth, objHeight, AnchorPosition.MIDDLECENTER);}	
			catch(e){}
			objFile.selection.selectAll();
			try {objFile.selection.copy(true); }			//copy merge resized image into clipboard
			catch(e){objFile.selection.copy(); }			//copy resized image into clipboard
			objFile.close(SaveOptions.DONOTSAVECHANGES);	//close image without saving changes		
			smartObject.paste();							//paste change smart object content from being empty
		}
		catch(e) { objFile.close(SaveOptions.DONOTSAVECHANGES); } // close image without saving changes smart object is empty though	
		if (smartObject.name.indexOf(".jpg")!=-1) smartObject.flatten();			
		smartObject.close(SaveOptions.SAVECHANGES);			//close and save
		theSO.visible =	lyrVis; 
        return app.activeDocument.activeLayer    
    }     
	catch(e) { alert(e + "\nFile " + newFile, 'editContents', true); }	
}     	

////// open smart object //////
function openSmartObject (theLayer) {
	current = app.activeDocument;
	if (theLayer.kind == "LayerKind.SMARTOBJECT") {
		runMenuItem(stringIDToTypeID('placedLayerEditContents'));
		if ( current == app.activeDocument) {
			try {         
				var r = new ActionReference();     
				r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("smartObject"));  
				r.putIdentifier(stringIDToTypeID("layer"), theLayer.id);  
				var name = executeActionGet(r).getObjectValue(stringIDToTypeID("smartObject")).getString(stringIDToTypeID("fileReference"));         
				}  
			catch (e) { throw theLayer + " Smart Object Did not Open"; }  
			var workFile = new File(Folder.temp + "/" +  name);  // May work for both Windows and Mac
			if (workFile.exists) app.open(File(workFile));
			if ( current == app.activeDocument) throw theLayer + " Smart Object Did not Open";
		}
	}
	return app.activeDocument
};

function SaveAsJPEG(saveFile, jpegQuality){
	var doc = activeDocument;
	if (doc.bitsPerChannel != BitsPerChannelType.EIGHT) doc.bitsPerChannel = BitsPerChannelType.EIGHT;
	jpgSaveOptions = new JPEGSaveOptions();
	jpgSaveOptions.embedColorProfile = true;
	jpgSaveOptions.formatOptions = FormatOptions.STANDARDBASELINE;
	jpgSaveOptions.matte = MatteType.NONE;
	jpgSaveOptions.quality = jpegQuality;
	activeDocument.saveAs(File(saveFile+".jpg"), jpgSaveOptions, true,Extension.LOWERCASE);
}

function SaveAsPSD( inFileName, inEmbedICC ) {
	var psdSaveOptions = new PhotoshopSaveOptions();
	psdSaveOptions.embedColorProfile = inEmbedICC;
	app.activeDocument.saveAs( File( inFileName + ".psd" ), psdSaveOptions );
}

function help() {
	try{
		var URL = new File(Folder.temp + "/PhotoCollageToolkit.html");
		URL.open("w");
		URL.writeln('<html><HEAD><meta HTTP-EQUIV="REFRESH" content="0; url=http://www.mouseprints.net/old/dpr/PhotoCollageToolkit.html"></HEAD></HTML>');
		URL.close();
		URL.execute();
	}catch(e){
		alert("Error, Can Not Open.");
	};
}

///////////////////////////////////////////////////////////////////////////////
// Function: initExportInfo
// Usage: create our default parameters
// Input: a new Object
// Return: a new object with params set to default
///////////////////////////////////////////////////////////////////////////////
function initExportInfo(exportInfo) {
    exportInfo.destination = new String("");
    exportInfo.fileNamePrefix = new String("untitled_");
    exportInfo.visibleOnly = false;
//    exportInfo.fileType = psdIndex;
    exportInfo.icc = true;
    exportInfo.jpegQuality = 8;
    exportInfo.psdMaxComp = true;
    exportInfo.tiffCompression = TIFFEncoding.NONE;
    exportInfo.tiffJpegQuality = 8;
    exportInfo.pdfEncoding = PDFEncoding.JPEG;
    exportInfo.pdfJpegQuality = 8;
    exportInfo.targaDepth = TargaBitsPerPixels.TWENTYFOUR;
    exportInfo.bmpDepth = BMPDepthType.TWENTYFOUR;

    try {
         exportInfo.destination = Folder(app.activeDocument.fullName.parent).fsName; // destination folder
        var tmp = app.activeDocument.fullName.name;
        exportInfo.fileNamePrefix = decodeURI(tmp.substring(0, tmp.indexOf("."))); // filename body part
    } catch(someError) {
        exportInfo.destination = new String("");
//        exportInfo.fileNamePrefix = app.activeDocument.name; // filename body part
    }
}

// Find the location where this script resides
function findScript() {
	var where = "";
	try {
		FORCEERROR = FORCERRROR;
	}
	catch(err) {
		// alert(err.fileName);
		// alert(File(err.fileName).exists);
		where = File(err.fileName);
	}
	return where;
}

function timeString () {
  var now = new Date();
  return now.getTime()
};

// Function for returning current date and time
    function getDateTime() {
        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;
    }

// resetPrefs function for resetting the preferences
	function resetPrefs() {
		preferences.rulerUnits = startRulerUnits;
		preferences.typeUnits = startTypeUnits;
		displayDialogs = startDisplayDialogs;
	}

// CheckVersion
function CheckVersion() {
	var numberArray = version.split(".");
	if ( numberArray[0] < 9 ) {
		alert( "You must use Photoshop CS2 or later to run this script!" );
		throw( "You must use Photoshop CS2 or later to run this script!" );
	}
}

// load my params from the xml file on disk if it exists
// gParams["myoptionname"] = myoptionvalue
// I wrote a very simple xml parser, I'm sure it needs work
function LoadParamsFromDisk ( loadFile, params ) {
	// var params = new Array();
	if ( loadFile.exists ) {
		loadFile.open( "r" );
		var projectSpace = ReadHeader( loadFile );
		if ( projectSpace == GetScriptNameForXML() ) {
			while ( ! loadFile.eof ) {
				var starter = ReadHeader( loadFile );
				var data = ReadData( loadFile );
				var ender = ReadHeader( loadFile );
				if ( ( "/" + starter ) == ender ) {
					params[starter] = data;
				}
				// force boolean values to boolean types
				if ( data == "true" || data == "false" ) {
					params[starter] = data == "true";
				}
			}
		}
		loadFile.close();
		if ( params["version"] != gVersion ) {
			// do something here to fix version conflicts
			// this should do it
			params["version"] = gVersion;
		}
	}
	return params;
}

// save out my params, this is much easier
function SaveParamsToDisk ( saveFile, params ) {
	saveFile.encoding = "UTF8";
	saveFile.open( "w", "TEXT", "????" );
	// unicode signature, this is UTF16 but will convert to UTF8 "EF BB BF"
	saveFile.write("\uFEFF");
	var scriptNameForXML = GetScriptNameForXML();
	saveFile.writeln( "<" + scriptNameForXML + ">" );
	for ( var p in params ) {
		saveFile.writeln( "\t<" + p + ">" + params[p] + "</" + p + ">" );
	}
	saveFile.writeln( "</" + scriptNameForXML + ">" );
	saveFile.close();
}

// you can't save certain characters in xml, strip them here
// this list is not complete
function GetScriptNameForXML () {
	var scriptNameForXML = new String( gScriptName );
	var charsToStrip = Array( " ", "'", "." );
	for (var a = 0; a < charsToStrip.length; a++ )  {
		var nameArray = scriptNameForXML.split( charsToStrip[a] );
		scriptNameForXML = "";
		for ( var b = 0; b < nameArray.length; b++ ) {
			scriptNameForXML += nameArray[b];
		}
	}
	return scriptNameForXML;
}

// figure out what I call my params file
function GetDefaultParamsFile() {
	//var paramsFolder = new Folder( path + "/Presets/" + gScriptName );
	//var paramsFolder = new Folder( Folder.temp + "/JJMack's Scripts/" + gScriptName );
	var paramsFolder = new Folder( "~/Application Data/JJMack's Scripts/" + gScriptName );
	//alert("paramsFolder = " + paramsFolder );
	paramsFolder.create();
	return ( new File( paramsFolder + "/" + gScriptName + ".xml" ) );
}

// a very crude xml parser, this reads the "Tag" of the <Tag>Data</Tag>
function ReadHeader( inFile ) {
	var returnValue = "";
	if ( ! inFile.eof ) {
		var c = "";
		while ( c != "<" && ! inFile.eof ) {
			c = inFile.read( 1 );
		}
		while ( c != ">" && ! inFile.eof ) {
			c = inFile.read( 1 );
			if ( c != ">" ) {
				returnValue += c;
			}
		}
	} else {
		returnValue = "end of file";
	}
	return returnValue;
}

// very crude xml parser, this reads the "Data" of the <Tag>Data</Tag>
function ReadData( inFile ) {
	var returnValue = "";
	if ( ! inFile.eof ) {
		var c = "";
		while ( c != "<" && ! inFile.eof ) {
			c = inFile.read( 1 );
			if ( c != "<" ) {
				returnValue += c;
			}
		}
		inFile.seek( -1, 1 );
	}
	return returnValue;
}

 

 

Sébastien15A7_1-1616172562053.png

 

 

Sébastien15A7_2-1616172651070.png

 

Unfortunately, I've got an issue when I try to replace the example's source files by my own source files.

Even though the proportion of my images seems to match my template, I always receive the following error message : 

 

Sébastien15A7_3-1616172793884.png

 

"Replacemen object counts are not the same "

 

Reading from the script I suppose it has to do with this part of the script

 

Sébastien15A7_10-1616174087974.png

... but since I don't know much about Java coding, I'm totally lost.

 

Could anyone help me make this work ?

 

I would quite literally save my life.

 

Thanks in advance,

 

 

Seb.

 

 

 

 

 

 

TOPICS
Actions and scripting, How to

Views

742

Likes

translate

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
Most Valuable Participant ,
Mar 19, 2021 Mar 19, 2021

Copy link to clipboard

Copied

image.png

You do not have the same number of replacement object in folders obj0 and obj1.  Forder obj0 has  10 replacemebts obj1 does not have exactly 10 replacement.

 

You may also have problems if your PNG files certain transparent boarders. Did you read the help?

JJMack

Likes

translate

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 ,
Mar 19, 2021 Mar 19, 2021

Copy link to clipboard

Copied

That's my main issue here :  there IS the same number of files in both obj0 and obj1 folders.

 

Sébastien15A7_1-1616195836752.png

 

(In this case, 5 files, but same error message)

 

However, now that you're saying it, there IS transparency in my TIF file and it's a thing I didn't see mentioned in the Help/instructions.

 

I'll give it a look tomorrow and will come back to communicate the resulsts.

 

Anyway, thanks for your help (and for the amazing work on the script), it really helps.

 

Seb.

Likes

translate

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
Most Valuable Participant ,
Mar 19, 2021 Mar 19, 2021

Copy link to clipboard

Copied

From what you posted

image.png

 

I see in File explorer you have targeted 5 files in obj0 and obj1. I see at least two files you have not targeted in obj1  The Message state the script sees 10 image files in folder obj0. All other folders obj"n"  need to have the same  number of image files.  10  image file are required to be in these folders no more no less. I see obj1 has at leasts two more  files then five targeted.   How many image files are in folder obj0 and how many image files are in obj1.  The message you prosted from my script state the script sees 10 image files in obj0 and does not see exactly  10 image files in obj1.

 

My scripts have a help button there is help for Collage and Mockup  Templates and scripts. Please read the help you seem toe be using mockup templates and scripts.

Simple Mockup Templates

Four Rules

  1. Simple Mockup Templates Only the Smart Object Layer on the top of the Template layers stack will be updated then a Jpeg file saved.
  2. Only Photoshop Objects are support in the top smart objects layers. That is they can not be Object File that are not supported by Photoshop like Camera RAW Files or Illustrator file like .ai, .svg.
    I suggest these objects should be PSD or PSB the Photoshop creates. Avoid using PNG objects in Mockup template use replace content to replace .png objects with a .psd which has your png's content.
  3. The first None Smart Object Layer near the top of the layer stack Marks the end of Smart Object Layers the will be updated. Lower Smart Object Layers only update if they share top layers objects.
  4. The Replacement Image Collection need to be in sub folders named obj0, obj1, obj2, .... objN. Each folder must contains the same number of replacement Image files.

Four Scripts

  1. BatchReplaceOneObject.jsx - Only the top Layer in the Layer Stack will be updated it must be a Smart Object Layer replacement images do not have to in a folder names obj0.
  2. BatchUpdateSmartObject.jsx - All top Smart Object layers in the Layers Stack will be updated.
    Replacement Images must be in sub-folders in some folder the sub-folder names must be obj(n) where n is (0,1,2...,v). Folder obj0 for top layer object replacement, obj1 next layer down etc.
  3. BatchMockupTemplates.jsx - Used to populate multiple Mockup Template that need to be populated with the same replacement image objects.
    Scripts "BatchReplaceOneObject.jsx" and "BatchUpdateSmartObject.jsx" are no longer required.
    All top Smart Object layers in the Layers Stack will be updated.
    Replacement Images must be in sub-folders in some folder the sub-folder names must be obj(n) where n is (0,1,2...,v). Folder obj0 for top layer object replacement, obj1 next layer down etc.
  4. PopulateAlbumPageMockups.jsx - Used to populate a collection of Photo Page Mockup templates for a Picture Album. This script is like the "BatchMockupTemplates.jsx" script However, just one set of replacement images is repopulated per mockup template. Each mockup template is for a pages in a table top Album.

Scripts Edit Options

  1. Edit Smart Objects - Replacement images will be sized to fill the layers Smart Object size. However, if the replacement image has a different aspect ratio than the object the fit will be a centred crop.
  2. Rotate for best fit - This Edit option can optionally rotate images orientation for a better fit. Helpful for picture package when replacement images files may be mixture of Landscape and Portrait images.
  3. Fit Image - Edit resizes replacement images to fill the smart object canvas size this can crop content like Logo replacements. Fit Image will not crop, however the smart object canvas will not be fully covered.
  4. Save PSD File - The updated Mockup will be saved as a Jpeg file use this option to save a layered version as well if you want to be able to edit the populated mockup.
JJMack

Likes

translate

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 ,
Mar 19, 2021 Mar 19, 2021

Copy link to clipboard

Copied

As JJMack wrote, the error means that you don't have say 100 files in Folder A and 100 files in Folder B. I'm hoping that you don't have 535,000 x2 being processed in one go!

 

I would suggest that you use one of JJMack's other scripts or one of many other scripts that are not based around smart objects. My gut feeling is that it would be faster to use simpler methods to combine the two images.

 

http://www.mouseprints.net/old/dpr/PhotoCollageToolkit.html

http://www.mouseprints.net/old/dpr/PhotoCollageToolkit.zip

 

There are many scripts to be found on this forum for combining pairs or "N" count of images together.

 

I made some very small changes to one of JJMack's scripts as it was not alphabetically sorting on the Mac, which meant that the incorrect files were being paired:

 

http://community.adobe.com/t5/Photoshop/Batch-automating-sequences-of-images/m-p/10619866#M263871 

https://github.com/MarshySwamp/Layer-Stack-N-Number-of-Files-Filename-as-Top-Layer

 

If you had an action that correctly combined two open files, then a script can open pairs of images and combine them using your action and repeat.

 

Likes

translate

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 ,
Mar 19, 2021 Mar 19, 2021

Copy link to clipboard

Copied

quote

As JJMack wrote, the error means that you don't have say 100 files in Folder A and 100 files in Folder B. I'm hoping that you don't have 535,000 x2 being processed in one go!

 

 

 

I would suggest that you use one of JJMack's other scripts or one of many other scripts that are not based around smart objects. My gut feeling is that it would be faster to use simpler methods to combine the two images.

 

http://www.mouseprints.net/old/dpr/PhotoCollageToolkit.html

http://www.mouseprints.net/old/dpr/PhotoCollageToolkit.zip

 

There are many scripts to be found on this forum for combining pairs or "N" count of images together.

 

I made some very small changes to one of JJMack's scripts as it was not alphabetically sorting on the Mac, which meant that the incorrect files were being paired:

 

http://community.adobe.com/t5/Photoshop/Batch-automating-sequences-of-images/m-p/10619866#M263871 

https://github.com/MarshySwamp/Layer-Stack-N-Number-of-Files-Filename-as-Top-Layer

 

If you had an action that correctly combined two open files, then a script can open pairs of images and combine them using your action and repeat.

 

Hi Stephen.

 

I confirm that I'm not trying to combine 535K x2 images in a single batch. 🙂

I totally agree that it would be simpler to not use smart objects but to be honest I havent found which of the scripts (out of the collage toolkit) would allow me to do that.

 

But again, it's mostly because I don't understand much about scripts so I'd love to be pointed towards one simpler that would fit my needs.

 

I didn't think of running the script as part of an action (if I understood your advice correctly). I'll give it a look tomorrow.

 

Thanks very much.

 

Seb.

Likes

translate

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 ,
Mar 19, 2021 Mar 19, 2021

Copy link to clipboard

Copied

EDIT: You could try JJMack's Multi Image Collage script.

 

Wrong way around, I meant that a script can play an action (but an action can also run a script).

 

Actions can't match pairs of images from one or more input folders.

 

Scripts can.

 

If you could create an action that correctly combined two open files, then a script can then open pairs of files, use the action to combine them and then the script would save the file and repeat. A script could also combine the files. For those that can't script, they can at least create an action. Then a combination of both script and action can get the job done.

 

Having three or more sets of full sized images (3 ads and 3 QR codes) would be required in order to offer specific help.

 

P.S. here are a couple of related topics, input from two folders combined into one image:

 

Likes

translate

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 ,
Mar 19, 2021 Mar 19, 2021

Copy link to clipboard

Copied

P.S. In your real files, is the QR code larger in size than the frame in the advertisement?

 

Your sample file posted above, the QR code is much larger than the frame in the ad, however, QR codes are not great content for resizing.

 

It appears to resize down OK, I'm not sure if the scan quality is affected or not.

Likes

translate

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 ,
Mar 24, 2021 Mar 24, 2021

Copy link to clipboard

Copied

Yes, I noticed that there was indeed a resize necessary to make both images match. 

 

The reason it resizes well is that I generated (on purpose) the QR codes in absolute black and white. I should have generated to the right size directly, TBH, but now that I've run a script generation for 535K files I would prefer not do it again. *laughs nervously*

 

Anyway, I understant what you meant in your previous message (having an action merge the images but the script open the pairs and save it). 

 

Here is a ZIP containing 10 pairs of images in full size.

 

https://drive.google.com/file/d/1vGxWw4PpmiwI9ABxfmMgd1y9V4DLfTAX/view?usp=sharing

 

 

Likes

translate

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 ,
Mar 19, 2021 Mar 19, 2021

Copy link to clipboard

Copied

 

Take the following image as an example:

 

script-calls-action.png

 

The script that I have modified for you to combine the two alphabetically sorting images will place the QR code centred on the advertisement image in multiply blend mode to make the white areas transparent... An action can move the QR code into the correct position and scale it to the correct size. That is all you need to do, the script does everything else! Of course the script could do that as well without an action, however, without access to the correct files for testing that is not currently possible. The script will then save the combined image using the QR code name and then close the original two files, then open up the next two files and repeat until all files in the two source folders are complete.

 

I am currently saving to PSD as I don't know what file format and options you specifically need... Are you using PNG as the final format? Save as or Save for Web? What settings/options when saving? I'm guessing that you don't want to add another step to use Image Processor or Image Processor Pro script to save the PSD to the final file format.

 

Likes

translate

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 ,
Mar 24, 2021 Mar 24, 2021

Copy link to clipboard

Copied

Actually, now that you're putting this out there, it makes me think of one element : 

 

My original QR images are in .svg format.

I had created a set of actions to convert them to true black and white and then save them to png so it could be read by a system unable to read vectorial files.

 

But now that I read your script below, I wonder if I could actually run three actions instead of two (Position & Size, Convert to BW, QR Set) with the "convert to BW" executing exactly what I have done in my previous image processing.

 

Regarding the saving of the image, the png format is indeed a necessity. Save as or Save for Web does not really matter, as long as the image is in true B&W (the system that prints it uses b&w and any greyscale due to a compression artifact messes up with the readability of the QR code).

 

While waiting for your answer, I'm already going to try and create my action set, add the BW conversion and run it, see if I can generate valid .psd files.

 

Thanks infinitely for your help. You have no idea of how much it saves my life.

 

Seb.

 

 

 

Likes

translate

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
Most Valuable Participant ,
Mar 19, 2021 Mar 19, 2021

Copy link to clipboard

Copied

You wrote:

"I made some very small changes to one of JJMack's scripts as it was not alphabetically sorting on the Mac, which meant that the incorrect files were being paired:"

 

There are differences between Microsoft Windows file systems and Unix file systems.  Microsoft file system is a bit strange when it comes to names while names can be mixed case there can one be one file with name "John" a file "jOHN" can not exist in the same folder that the is a "John" in.  Case does not matter for names in Windows File system but may matter for sorting.  So I left the file naming up to the user to create  the names so the file would be in the correct order.  There is no name matching in any of my scripts.  Folders are process in files system order.  Collage Template are populated from a single folder. The files need to be ordered is sets of images a set for each template.   While mokup  have seperate replacment folder for each smart object layer. There is no name matching between smart object layers folders. Windows folders are process in file name alphabetic order. I assumed  Apple file system would also.  I also never received a bug report form a Mac user about a file name sorting problem.  I have received feedback from some Mac users and had to add code to fix problem related to the  differences between Window and Mac systems.  My collage scripts are over 10 years old now.

 

Where did you have to add the sort for Mac OS.

JJMack

Likes

translate

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 ,
Mar 19, 2021 Mar 19, 2021

Copy link to clipboard

Copied

JJMack, I hacked your script to stack N amount of images on top of each other, which was not the original purpoase of your script.

 

The modified code is here, and the edit in question is documented on line 467:

 

https://github.com/MarshySwamp/Layer-Stack-N-Number-of-Files-Filename-as-Top-Layer/blob/master/Layer...

 

 

fileList.sort();

 

 

Or the reverse, depending on end use:

 

 

fileList.sort().reverse();

 

 

Since then, I have created my own scripts to stack N quantity of files, however, your script is of course much easier to use for those without any scripting knowledge.

Likes

translate

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
Most Valuable Participant ,
Mar 20, 2021 Mar 20, 2021

Copy link to clipboard

Copied

I'm a hacker myself.  I created the collage scripts back in the cs2 time frame. I knew nothing about scripting and there was a bug is Photoshop scripting selection bounds was broken.  Plug-in scripting support was then added to CS3 scripting and selection bounds was fixed.  I knew nothing about Photoshop scripting. Most of the code is reused code other had written or I had scriptlistener generate for me for I knew nothing. I have a been a hacker all my life it been useful and I'm not that bad at it.  I could be better at it if I could type. Typing is something I had to give up on I was dealt a loosing hands and brain when it come to data entry. Bring back the keypunch girls and verifiers. They even fixes my spelling...an other loosing battle of mine. You win some and loos some things in] life.

JJMack

Likes

translate

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 ,
Mar 23, 2021 Mar 23, 2021

Copy link to clipboard

Copied

 

Until I hear back on the specifics, this will have to do:

 

 

/*
Combine Banner and QR Code from 2 Folders.jsx
Stephen Marsh - 2021

NOTE:
* Change the action set and action name used to position and size the QR code

BatchUpdateSmartObjects.jsx - I'm in over my head... help ?
https://community.adobe.com/t5/photoshop/batchupdatesmartobjects-jsx-i-m-in-over-my-head-help/td-p/11911068

Script based on:

Auto merge files
http://community.adobe.com/t5/photoshop/auto-merge-files/m-p/10753387
*/

#target photoshop
app.bringToFront();

if (app.documents.length === 0) {

    (function main() {

        // Input folder 1 - TIFF banner ads
        var folder1 = Folder.selectDialog('Select the banner TIFF input folder', '~/Desktop');
        if (folder1 === null) return alert('Script cancelled!');

        // Input folder 2 - PNG QR codes
        var folder2 = Folder.selectDialog('Select the QR code PNG input folder', '~/Desktop');
        if (folder2 === null) return alert('Script cancelled!');

        // Limit the file format input & alphabetically sort
        var fileList1 = folder1.getFiles(/\.(tif|tiff)$/i);
        fileList1.sort();
        var fileList2 = folder2.getFiles(/\.(png)$/i);
        fileList2.sort();

        // Validate equal quantities of files in both input folders
        if (fileList1.length != fileList2.length) {
            alert('Script cancelled, both folders must have the same quantity of files!' + '\r' +
                'Folder 1 contains: ' + fileList1.length + ' TIFF files' + '\r' +
                'Folder 2 contains: ' + fileList2.length + ' PNG files'); return;
        }

        // Output folder - Save location
        var saveFolder = Folder.selectDialog('Select the save/output folder', '~/Desktop');
        if (saveFolder === null) return alert('Script cancelled!');

        // Set the dialogs
        var restoreDialogMode = app.displayDialogs;
        app.displayDialogs = DialogModes.NO;

        // Loop through the source folders and process the file pairs
        for (var i = 0; i < fileList1.length; i++) {

            // Open the TIFF banner
            var doc = open(fileList1[i]);

            // Place the PNG QR code without opening the doc!
            placeFile(fileList2[i], 100);

            // Set the QR code layer to multiply blend mode
            doc.activeLayer.blendMode = BlendMode.MULTIPLY;

            // Set doc save name to the QR code layer name
            var docName = app.activeDocument.activeLayer.name;


            //////////////////////// YOUR ACTION HERE! ////////////////////////
            // Action to run                                                 //
            var actionName = 'Position & Size Action';                       //
            // Action set to run                                             //
            var actionSet = 'QR Set';                                        //
            // Run the nominated action and set                              //
            app.doAction(actionName, actionSet);                             //
            ///////////////////////////////////////////////////////////////////


            // PSD format options
            var psdOptions = psdSaveOptions();

            // Save and close the combined file
            doc.saveAs(new File(saveFolder + '/' + docName.replace(/\.[^\.]+$/, '') + '.psd'), psdOptions);
            doc.close(SaveOptions.DONOTSAVECHANGES);

        };

        // Restore the original dialogs
        app.displayDialogs = restoreDialogMode;

        alert('Script completed!' + '\n' + fileList1.length + ' combined files saved to:' + '\r' + saveFolder.fsName);

        // Open the save folder in File Explorer or Finder
        saveFolder.execute();


        // Functions

        function placeFile(file, scale) {
            try {
                var idPlc = charIDToTypeID("Plc ");
                var desc2 = new ActionDescriptor();
                var idnull = charIDToTypeID("null");
                desc2.putPath(idnull, new File(file));
                var idFTcs = charIDToTypeID("FTcs");
                var idQCSt = charIDToTypeID("QCSt");
                var idQcsa = charIDToTypeID("Qcsa");
                desc2.putEnumerated(idFTcs, idQCSt, idQcsa);
                var idOfst = charIDToTypeID("Ofst");
                var desc3 = new ActionDescriptor();
                var idHrzn = charIDToTypeID("Hrzn");
                var idPxl = charIDToTypeID("#Pxl");
                desc3.putUnitDouble(idHrzn, idPxl, 0.000000);
                var idVrtc = charIDToTypeID("Vrtc");
                var idPxl = charIDToTypeID("#Pxl");
                desc3.putUnitDouble(idVrtc, idPxl, 0.000000);
                var idOfst = charIDToTypeID("Ofst");
                desc2.putObject(idOfst, idOfst, desc3);
                var idWdth = charIDToTypeID("Wdth");
                var idPrc = charIDToTypeID("#Prc");
                desc2.putUnitDouble(idWdth, idPrc, scale);
                var idHght = charIDToTypeID("Hght");
                var idPrc = charIDToTypeID("#Prc");
                desc2.putUnitDouble(idHght, idPrc, scale);
                var idAntA = charIDToTypeID("AntA");
                desc2.putBoolean(idAntA, true);
                executeAction(idPlc, desc2, DialogModes.NO);

            } catch (e) { }
        }

        function psdSaveOptions() {
            var psdOptions = new PhotoshopSaveOptions();
            psdOptions.embedColorProfile = true;
            psdOptions.alphaChannels = true;
            psdOptions.layers = true;
            psdOptions.spotColors = true;
            return psdOptions;
        }

    })();
}

else {
    alert('Close all files before running this script');
}

 

 

 

Likes

translate

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 ,
Mar 24, 2021 Mar 24, 2021

Copy link to clipboard

Copied

@Stephen_A_Marsh @JJMack  Sorry for not answering, I've got some family issues that have me kept from work for a few days.

 

I'll be reading your responses and answer as fully as possible in a few hours.

 

Sorry again for abandoning the both of you.

 

Seb.

Likes

translate

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 ,
Mar 25, 2021 Mar 25, 2021

Copy link to clipboard

Copied

So, here we go finally, I was able to create the actions and test the script : 

 

At first, I tried using directly the .svg files, as said in my comment above.

 

First I opened the background image.

 

1.jpg

4.jpg

 

Then I opened the .svg file which prompts a dialog. I just clicked ok (keeping the actual size of the .svg image). I assumed that's what the script would do.

 

2.jpg3.jpg

 

I then copied the QR and pasted it on top of the background (with layer option "multiply", since I understood that's what the script was doing).

 

5.jpg

 

From that point, I started recording actions. As you can see, I have created three actions : a resize action, a place action and I added a "threshold" action to convert the QR layer to absolute B&W.

The final result from the action on the side was this.

 

6.jpg

 

I closed the files, reopened them, ran the actions and confirmed it was working every time.

 

From there, I slightly modified the script so that the dialogs would show me the root of my image files, that it would process .svg and .png files, and that it would display the correct error messages.

 

/*
Combine Banner and QR Code from 2 Folders.jsx
Stephen Marsh - 2021

NOTE:
* Change the action set and action name used to position and size the QR code

BatchUpdateSmartObjects.jsx - I'm in over my head... help ?
https://community.adobe.com/t5/photoshop/batchupdatesmartobjects-jsx-i-m-in-over-my-head-help/td-p/11911068

Script based on:

Auto merge files
http://community.adobe.com/t5/photoshop/auto-merge-files/m-p/10753387
*/

#target photoshop
app.bringToFront();

if (app.documents.length === 0) {

    (function main() {

        // Input folder 1 - TIFF banner ads
        var folder1 = Folder.selectDialog('Select the banner Banner input folder', '~/Desktop/Test PNG QR pour batch merge/BANNERS');
        if (folder1 === null) return alert('Script cancelled!');

        // Input folder 2 - PNG QR codes
        var folder2 = Folder.selectDialog('Select the QR code input folder', '~/Desktop/Test PNG QR pour batch merge/BANNERS');
        if (folder2 === null) return alert('Script cancelled!');

        // Limit the file format input & alphabetically sort
        var fileList1 = folder1.getFiles(/\.(png)$/i);
        fileList1.sort();
        var fileList2 = folder2.getFiles(/\.(svg)$/i);
        fileList2.sort();

        // Validate equal quantities of files in both input folders
        if (fileList1.length != fileList2.length) {
            alert('Script cancelled, both folders must have the same quantity of files!' + '\r' +
                'Folder 1 contains: ' + fileList1.length + ' PNG files' + '\r' +
                'Folder 2 contains: ' + fileList2.length + ' svg files'); return;
        }

        // Output folder - Save location
        var saveFolder = Folder.selectDialog('Select the save/output folder', '~/Desktop');
        if (saveFolder === null) return alert('Script cancelled!');

        // Set the dialogs
        var restoreDialogMode = app.displayDialogs;
        app.displayDialogs = DialogModes.NO;

        // Loop through the source folders and process the file pairs
        for (var i = 0; i < fileList1.length; i++) {

            // Open the banner
            var doc = open(fileList1[i]);

            // Place the QR code without opening the doc!
            placeFile(fileList2[i], 100);

            // Set the QR code layer to multiply blend mode
            doc.activeLayer.blendMode = BlendMode.MULTIPLY;

            // Set doc save name to the QR code layer name
            var docName = app.activeDocument.activeLayer.name;


            //////////////////////// YOUR ACTION HERE! ////////////////////////
            // Action to run                                                 //
            var actionName = 'Position & Size Action';                       //
            // Action set to run                                             //
            var actionSet = 'QR Set from SVG';                                        //
            // Run the nominated action and set                              //
            app.doAction(actionName, actionSet);                             //
            ///////////////////////////////////////////////////////////////////


            // PSD format options
            var psdOptions = psdSaveOptions();

            // Save and close the combined file
            doc.saveAs(new File(saveFolder + '/' + docName.replace(/\.[^\.]+$/, '') + '.psd'), psdOptions);
            doc.close(SaveOptions.DONOTSAVECHANGES);

        };

        // Restore the original dialogs
        app.displayDialogs = restoreDialogMode;

        alert('Script completed!' + '\n' + fileList1.length + ' combined files saved to:' + '\r' + saveFolder.fsName);

        // Open the save folder in File Explorer or Finder
        saveFolder.execute();


        // Functions

        function placeFile(file, scale) {
            try {
                var idPlc = charIDToTypeID("Plc ");
                var desc2 = new ActionDescriptor();
                var idnull = charIDToTypeID("null");
                desc2.putPath(idnull, new File(file));
                var idFTcs = charIDToTypeID("FTcs");
                var idQCSt = charIDToTypeID("QCSt");
                var idQcsa = charIDToTypeID("Qcsa");
                desc2.putEnumerated(idFTcs, idQCSt, idQcsa);
                var idOfst = charIDToTypeID("Ofst");
                var desc3 = new ActionDescriptor();
                var idHrzn = charIDToTypeID("Hrzn");
                var idPxl = charIDToTypeID("#Pxl");
                desc3.putUnitDouble(idHrzn, idPxl, 0.000000);
                var idVrtc = charIDToTypeID("Vrtc");
                var idPxl = charIDToTypeID("#Pxl");
                desc3.putUnitDouble(idVrtc, idPxl, 0.000000);
                var idOfst = charIDToTypeID("Ofst");
                desc2.putObject(idOfst, idOfst, desc3);
                var idWdth = charIDToTypeID("Wdth");
                var idPrc = charIDToTypeID("#Prc");
                desc2.putUnitDouble(idWdth, idPrc, scale);
                var idHght = charIDToTypeID("Hght");
                var idPrc = charIDToTypeID("#Prc");
                desc2.putUnitDouble(idHght, idPrc, scale);
                var idAntA = charIDToTypeID("AntA");
                desc2.putBoolean(idAntA, true);
                executeAction(idPlc, desc2, DialogModes.NO);

            } catch (e) { }
        }

        function psdSaveOptions() {
            var psdOptions = new PhotoshopSaveOptions();
            psdOptions.embedColorProfile = true;
            psdOptions.alphaChannels = true;
            psdOptions.layers = true;
            psdOptions.spotColors = true;
            return psdOptions;
        }

    })();
}

else {
    alert('Close all files before running this script');
}

 

 

I then ran it and was pleased that it ran without mistakes.

 

7.jpg

 

Unfortunately, when I opened the files generated, I noticed that the QR layer is moved far on the left (out of the canvas) and is too small.

 

8.jpg

 

Since then, I've tried to tinker with the placing and resizing parameters, creating several sets of actions, hoping I'd find the right placement but without reaching my goal.

 

So I'm now blocked again and hoping @Stephen_A_Marsh to point exactly to my noob mistake before I can fix it. 😞

 

Also, I've found a script to save the merged image to .pgn but I'm not sure how to combine both scripts.

 

if (app.documents.length != 0) {
    var doc= app.activeDocument;

    for (i = 0; i < 5; i++) {
        var layer = doc.artLayers[0]
        layer.textItem.contents = i;

        var opts, file;
        opts = new ExportOptionsSaveForWeb();
        opts.format = SaveDocumentType.PNG;
        opts.PNG8 = false;
        opts.quality = 100;

        pngFile = new File("/Users/dlokshin/temp/speed.png");
        app.activeDocument.exportDocument(pngFile, ExportType.SAVEFORWEB, opts);
    }
}

 

So, yeah, I swear some day I'll learn javascript coding basics instead of begging for help.

 

Until now, thanks 100.000 times for the help !

 

 

Seb.

 

 

(PS : Excuse the purple censoring. It's messy but I'm kinda forced to do it.)

 

 

 

 

 

 

Likes

translate

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 ,
Mar 25, 2021 Mar 25, 2021

Copy link to clipboard

Copied

You can send me a PM if you like as I'll need copies of production files at the correct sizes etc in order to make the required changes.

 

Otherwise what happens if you go back to my original script and use the PNG QR code's?

Likes

translate

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 ,
Mar 26, 2021 Mar 26, 2021

Copy link to clipboard

Copied

Here is an updated script and referenced action linked below.  Please test that the QR codes are readable and take the user to the corresponding destination as the banner. Let me know how this goes...

 

 

/*
Combine Banner and QR Code from 2 Folders.jsx
Stephen Marsh - Updated 27th March 2021

NOTE:
* Change the action set and action name used to position and size the QR code

BatchUpdateSmartObjects.jsx - I'm in over my head... help ?
https://community.adobe.com/t5/photoshop/batchupdatesmartobjects-jsx-i-m-in-over-my-head-help/td-p/11911068

Script based on:

Auto merge files
http://community.adobe.com/t5/photoshop/auto-merge-files/m-p/10753387
*/

#target photoshop
app.bringToFront();

if (app.documents.length === 0) {

    (function main() {

        // Input folder 1 - PNG banner ads
        var folder1 = Folder.selectDialog('Select the banner PNG input folder');
        if (folder1 === null) return alert('Script cancelled!');

        // Input folder 2 - SVG QR codes
        var folder2 = Folder.selectDialog('Select the QR code SVG input folder');
        if (folder2 === null) return alert('Script cancelled!');

        // Limit the file format input & alphabetically sort
        var fileList1 = folder1.getFiles(/\.(png)$/i);
        fileList1.sort();
        var fileList2 = folder2.getFiles(/\.(svg)$/i);
        fileList2.sort();

        // Validate equal quantities of files in both input folders
        if (fileList1.length != fileList2.length) {
            alert('Script cancelled, both folders must have the same quantity of files!' + '\r' +
                'Folder 1 contains: ' + fileList1.length + ' PNG files' + '\r' +
                'Folder 2 contains: ' + fileList2.length + ' SVG files');
            return;
        }
        // Check if the input folders were selected in the reverse order
        else if (fileList1.length === 0) {
            alert('Script cancelled, no matching files found! Did you select the folders in the wrong order?');
            return;
        }

        // Output folder - Export location
        var exportFolder = Folder.selectDialog('Select the export folder');
        if (exportFolder === null) return alert('Script cancelled!');

        // Set the dialogs
        var restoreDialogMode = app.displayDialogs;
        app.displayDialogs = DialogModes.NO;
        var savedRuler = app.preferences.rulerUnits;
        app.preferences.rulerUnits = Units.PIXELS;

        // Loop through the source folders and process the file pairs
        for (var i = 0; i < fileList1.length; i++) {

            // Open the PNG banner
            var doc = open(fileList1[i]);

            // Place the SVG QR code without opening the doc!
            placeFile(fileList2[i], 100);

            // Set the QR code layer to multiply blend mode
            doc.activeLayer.blendMode = BlendMode.MULTIPLY;

            // Set doc export name to the QR code layer name
            var docName = app.activeDocument.activeLayer.name;


            /////////////// YOUR ACTION HERE! ///////////////
            // Action to run                               //
            var actionName = 'Position & Size Action';     //
            // Action set to run                           //
            var actionSet = 'QR Set';                      //
            // Run the nominated action and set            //
            app.doAction(actionName, actionSet);           //
            /////////////////////////////////////////////////


            // Export and close the combined file
            var pngOptions = pngExportOptions();
            doc.exportDocument(File(exportFolder + '/' + docName.replace(/\.[^\.]+$/, '') + '.png'), ExportType.SAVEFORWEB, pngOptions);
            doc.close(SaveOptions.DONOTSAVECHANGES);

        }

        // Restore the original dialogs
        app.displayDialogs = restoreDialogMode;
        app.preferences.rulerUnits = savedRuler;

        alert('Script completed!' + '\n' + fileList1.length + ' combined files exported to:' + '\r' + exportFolder.fsName);

        // Open the destination folder in File Explorer or Finder
        exportFolder.execute();


        // Functions

        function placeFile(file, scale) {
            try {
                var idPlc = charIDToTypeID("Plc ");
                var desc2 = new ActionDescriptor();
                var idnull = charIDToTypeID("null");
                desc2.putPath(idnull, new File(file));
                var idFTcs = charIDToTypeID("FTcs");
                var idQCSt = charIDToTypeID("QCSt");
                var idQcsa = charIDToTypeID("Qcsa");
                desc2.putEnumerated(idFTcs, idQCSt, idQcsa);
                var idOfst = charIDToTypeID("Ofst");
                var desc3 = new ActionDescriptor();
                var idHrzn = charIDToTypeID("Hrzn");
                var idPxl = charIDToTypeID("#Pxl");
                desc3.putUnitDouble(idHrzn, idPxl, 0.000000);
                var idVrtc = charIDToTypeID("Vrtc");
                var idPxl = charIDToTypeID("#Pxl");
                desc3.putUnitDouble(idVrtc, idPxl, 0.000000);
                var idOfst = charIDToTypeID("Ofst");
                desc2.putObject(idOfst, idOfst, desc3);
                var idWdth = charIDToTypeID("Wdth");
                var idPrc = charIDToTypeID("#Prc");
                desc2.putUnitDouble(idWdth, idPrc, scale);
                var idHght = charIDToTypeID("Hght");
                var idPrc = charIDToTypeID("#Prc");
                desc2.putUnitDouble(idHght, idPrc, scale);
                var idAntA = charIDToTypeID("AntA");
                desc2.putBoolean(idAntA, true);
                executeAction(idPlc, desc2, DialogModes.NO);

            } catch (e) { }
        }

        function pngExportOptions() {
            var pngOptions = new ExportOptionsSaveForWeb();
            pngOptions.PNG8 = false;
            pngOptions.transparency = true;
            pngOptions.interlaced = false;
            pngOptions.quality = 100;
            pngOptions.includeProfile = false;
            pngOptions.format = SaveDocumentType.PNG;
        }

    })();
} else {
    alert('Close all files before running this script');
}

 

 

Here is a link to the action based on your sample PNG banner and SVG qr code files:

 

https://www.dropbox.com/s/0otm92a0trsnlin/QR%20Set.atn?dl=0

 

Likes

translate

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 ,
Mar 26, 2021 Mar 26, 2021

Copy link to clipboard

Copied

You, Sir, are a life saver.

 

10.jpg

 

 

As you can see, the QR is now exactly at the right place.

 

I just added a "rasterize" action in your action set right before saving.

 

However, the output png is readable in the Windows Preview and Paint but not in Photoshop.

 

9.jpg

 

I don't think this is gonna be an issue for the final use of my files but if you know why this happens, I'd love to learn more about it. (I had the same issue with the files generated by your script before I added the rasterize option.)

 

Anyway, thanks for your work, kind Sir. If you DM me some personal detail, I'll be pleased to send you some of the specialities from my country (Belgium) as a way to show my gratitute. 🙂

 

 

Likes

translate

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 ,
Mar 27, 2021 Mar 27, 2021

Copy link to clipboard

Copied

I need to look into why the PNG files are not being recognised, I think I messed up something simple that I can't spot! ExifTool states that they are actually JPEG files...

Likes

translate

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 ,
Mar 27, 2021 Mar 27, 2021

Copy link to clipboard

Copied

I'm not happy with this fix, but it should hopefully resolve the PNG as JPEG issue for now... I still don't know why the issue came up in the first place. I'd like to say a bug, however, it is probably my coding.

 

 

/*
Combine Banner and QR Code from 2 Folders.jsx
Stephen Marsh - Updated 27th March 2021

NOTE:
* Change the action set and action name used to position and size the QR code

BatchUpdateSmartObjects.jsx - I'm in over my head... help ?
https://community.adobe.com/t5/photoshop/batchupdatesmartobjects-jsx-i-m-in-over-my-head-help/td-p/11911068

Script based on:

Auto merge files
http://community.adobe.com/t5/photoshop/auto-merge-files/m-p/10753387
*/

#target photoshop
app.bringToFront();

if (app.documents.length === 0) {

    (function main() {

        // Input folder 1 - PNG banner ads
        var folder1 = Folder.selectDialog('Select the banner PNG input folder');
        if (folder1 === null) return alert('Script cancelled!');

        // Input folder 2 - SVG QR codes
        var folder2 = Folder.selectDialog('Select the QR code SVG input folder');
        if (folder2 === null) return alert('Script cancelled!');

        // Limit the file format input & alphabetically sort
        var fileList1 = folder1.getFiles(/\.(png)$/i);
        fileList1.sort();
        var fileList2 = folder2.getFiles(/\.(svg)$/i);
        fileList2.sort();

        // Validate equal quantities of files in both input folders
        if (fileList1.length != fileList2.length) {
            alert('Script cancelled, both folders must have the same quantity of files!' + '\r' +
                'Folder 1 contains: ' + fileList1.length + ' PNG files' + '\r' +
                'Folder 2 contains: ' + fileList2.length + ' SVG files');
            return;
        }
        // Check if the input folders were selected in the reverse order
        else if (fileList1.length === 0) {
            alert('Script cancelled, no matching files found! Did you select the folders in the wrong order?');
            return;
        }

        // Output folder - Export location
        var exportFolder = Folder.selectDialog('Select the export folder');
        if (exportFolder === null) return alert('Script cancelled!');

        // Set the dialogs
        var restoreDialogMode = app.displayDialogs;
        app.displayDialogs = DialogModes.NO;
        var savedRuler = app.preferences.rulerUnits;
        app.preferences.rulerUnits = Units.PIXELS;

        // Loop through the source folders and process the file pairs
        for (var i = 0; i < fileList1.length; i++) {

            // Open the PNG banner
            var doc = open(fileList1[i]);

            // Place the SVG QR code without opening the doc!
            placeFile(fileList2[i], 100);

            // Set the QR code layer to multiply blend mode
            doc.activeLayer.blendMode = BlendMode.MULTIPLY;

            // Set doc export name to the QR code layer name
            var docName = app.activeDocument.activeLayer.name;


            //////////////// YOUR ACTION HERE! ////////////////
            // Action to run                                 //
            var actionName = 'Position & Size Action';       //
            // Action set to run                             //
            var actionSet = 'QR Set';                        //
            // Run the nominated action and set              //
            app.doAction(actionName, actionSet);             //
            ///////////////////////////////////////////////////


            // PNG format options
            var pngOptions = pngExport();

            // Export and close the combined file
            doc.exportDocument(File(exportFolder + '/' + docName.replace(/\.[^\.]+$/, '') + '.png'), ExportType.SAVEFORWEB, pngOptions);
            doc.close(SaveOptions.DONOTSAVECHANGES);

        }

        // Restore the original dialogs
        app.displayDialogs = restoreDialogMode;
        app.preferences.rulerUnits = savedRuler;

        alert('Script completed!' + '\n' + fileList1.length + ' combined files exported to:' + '\r' + exportFolder.fsName);

        // Open the destination folder in File Explorer or Finder
        exportFolder.execute();


        // Functions

        function placeFile(file, scale) {
            try {
                var idPlc = charIDToTypeID("Plc ");
                var desc2 = new ActionDescriptor();
                var idnull = charIDToTypeID("null");
                desc2.putPath(idnull, new File(file));
                var idFTcs = charIDToTypeID("FTcs");
                var idQCSt = charIDToTypeID("QCSt");
                var idQcsa = charIDToTypeID("Qcsa");
                desc2.putEnumerated(idFTcs, idQCSt, idQcsa);
                var idOfst = charIDToTypeID("Ofst");
                var desc3 = new ActionDescriptor();
                var idHrzn = charIDToTypeID("Hrzn");
                var idPxl = charIDToTypeID("#Pxl");
                desc3.putUnitDouble(idHrzn, idPxl, 0.000000);
                var idVrtc = charIDToTypeID("Vrtc");
                var idPxl = charIDToTypeID("#Pxl");
                desc3.putUnitDouble(idVrtc, idPxl, 0.000000);
                var idOfst = charIDToTypeID("Ofst");
                desc2.putObject(idOfst, idOfst, desc3);
                var idWdth = charIDToTypeID("Wdth");
                var idPrc = charIDToTypeID("#Prc");
                desc2.putUnitDouble(idWdth, idPrc, scale);
                var idHght = charIDToTypeID("Hght");
                var idPrc = charIDToTypeID("#Prc");
                desc2.putUnitDouble(idHght, idPrc, scale);
                var idAntA = charIDToTypeID("AntA");
                desc2.putBoolean(idAntA, true);
                executeAction(idPlc, desc2, DialogModes.NO);

            } catch (e) { }
        }

        function pngExport() {
            exportPNG24(true, new File(exportFolder), false, true, true, false, 255, 255, 255, false, true, false, true, true, true, false, true, -1, false, false, "", false, false, true, true, true, "images");

            function exportPNG24(DIDr, In, Intr, Trns, Mtt, EICC, MttR, MttG, MttB, SHTM, SImg, ohXH, ohIC, ohAA, ohQA, ohCA, ohIZ, ohIn, olCS, obIA, obIP, ovCM, ovCW, ovCU, ovSF, ovCB, ovSN) {
                var c2t = function (s) {
                    return app.charIDToTypeID(s);
                };

                var s2t = function (s) {
                    return app.stringIDToTypeID(s);
                };

                var descriptor = new ActionDescriptor();
                var descriptor2 = new ActionDescriptor();
                var descriptor3 = new ActionDescriptor();
                var descriptor4 = new ActionDescriptor();
                var descriptor5 = new ActionDescriptor();
                var descriptor6 = new ActionDescriptor();
                var descriptor7 = new ActionDescriptor();
                var descriptor8 = new ActionDescriptor();
                var descriptor9 = new ActionDescriptor();
                var descriptor10 = new ActionDescriptor();
                var descriptor11 = new ActionDescriptor();
                var descriptor12 = new ActionDescriptor();
                var descriptor13 = new ActionDescriptor();
                var descriptor14 = new ActionDescriptor();
                var descriptor15 = new ActionDescriptor();
                var descriptor16 = new ActionDescriptor();
                var descriptor17 = new ActionDescriptor();
                var list = new ActionList();
                var list2 = new ActionList();

                descriptor2.putEnumerated(c2t("Op  "), c2t("SWOp"), c2t("OpSa"));
                descriptor2.putBoolean(c2t("DIDr"), DIDr);
                descriptor2.putPath(c2t("In  "), In);
                descriptor2.putEnumerated(s2t("format"), c2t("IRFm"), c2t("PN24"));
                descriptor2.putBoolean(c2t("Intr"), Intr);
                descriptor2.putBoolean(c2t("Trns"), Trns);
                descriptor2.putBoolean(c2t("Mtt "), Mtt);
                descriptor2.putBoolean(c2t("EICC"), EICC);
                descriptor2.putInteger(c2t("MttR"), MttR);
                descriptor2.putInteger(c2t("MttG"), MttG);
                descriptor2.putInteger(c2t("MttB"), MttB);
                descriptor2.putBoolean(c2t("SHTM"), SHTM);
                descriptor2.putBoolean(c2t("SImg"), SImg);
                descriptor2.putEnumerated(c2t("SWsl"), c2t("STsl"), c2t("SLAl"));
                descriptor2.putEnumerated(c2t("SWch"), c2t("STch"), c2t("CHDc"));
                descriptor2.putEnumerated(c2t("SWmd"), c2t("STmd"), c2t("MDNn"));
                descriptor2.putBoolean(c2t("ohXH"), ohXH);
                descriptor2.putBoolean(c2t("ohIC"), ohIC);
                descriptor2.putBoolean(c2t("ohAA"), ohAA);
                descriptor2.putBoolean(c2t("ohQA"), ohQA);
                descriptor2.putBoolean(c2t("ohCA"), ohCA);
                descriptor2.putBoolean(c2t("ohIZ"), ohIZ);
                descriptor2.putEnumerated(c2t("ohTC"), c2t("SToc"), c2t("OC03"));
                descriptor2.putEnumerated(c2t("ohAC"), c2t("SToc"), c2t("OC03"));
                descriptor2.putInteger(c2t("ohIn"), ohIn);
                descriptor2.putEnumerated(c2t("ohLE"), c2t("STle"), c2t("LE03"));
                descriptor2.putEnumerated(c2t("ohEn"), c2t("STen"), c2t("EN00"));
                descriptor2.putBoolean(c2t("olCS"), olCS);
                descriptor2.putEnumerated(c2t("olEC"), c2t("STst"), c2t("ST00"));
                descriptor2.putEnumerated(c2t("olWH"), c2t("STwh"), c2t("WH01"));
                descriptor2.putEnumerated(c2t("olSV"), c2t("STsp"), c2t("SP04"));
                descriptor2.putEnumerated(c2t("olSH"), c2t("STsp"), c2t("SP04"));
                descriptor3.putEnumerated(c2t("ncTp"), c2t("STnc"), c2t("NC00"));
                list.putObject(c2t("SCnc"), descriptor3);
                descriptor4.putEnumerated(c2t("ncTp"), c2t("STnc"), c2t("NC19"));
                list.putObject(c2t("SCnc"), descriptor4);
                descriptor5.putEnumerated(c2t("ncTp"), c2t("STnc"), c2t("NC28"));
                list.putObject(c2t("SCnc"), descriptor5);
                descriptor6.putEnumerated(c2t("ncTp"), c2t("STnc"), c2t("NC24"));
                list.putObject(c2t("SCnc"), descriptor6);
                descriptor7.putEnumerated(c2t("ncTp"), c2t("STnc"), c2t("NC24"));
                list.putObject(c2t("SCnc"), descriptor7);
                descriptor8.putEnumerated(c2t("ncTp"), c2t("STnc"), c2t("NC24"));
                list.putObject(c2t("SCnc"), descriptor8);
                descriptor2.putList(c2t("olNC"), list);
                descriptor2.putBoolean(c2t("obIA"), obIA);
                descriptor2.putString(c2t("obIP"), obIP);
                descriptor2.putEnumerated(c2t("obCS"), c2t("STcs"), c2t("CS01"));
                descriptor9.putEnumerated(c2t("ncTp"), c2t("STnc"), c2t("NC01"));
                list2.putObject(c2t("SCnc"), descriptor9);
                descriptor10.putEnumerated(c2t("ncTp"), c2t("STnc"), c2t("NC20"));
                list2.putObject(c2t("SCnc"), descriptor10);
                descriptor11.putEnumerated(c2t("ncTp"), c2t("STnc"), c2t("NC02"));
                list2.putObject(c2t("SCnc"), descriptor11);
                descriptor12.putEnumerated(c2t("ncTp"), c2t("STnc"), c2t("NC19"));
                list2.putObject(c2t("SCnc"), descriptor12);
                descriptor13.putEnumerated(c2t("ncTp"), c2t("STnc"), c2t("NC06"));
                list2.putObject(c2t("SCnc"), descriptor13);
                descriptor14.putEnumerated(c2t("ncTp"), c2t("STnc"), c2t("NC24"));
                list2.putObject(c2t("SCnc"), descriptor14);
                descriptor15.putEnumerated(c2t("ncTp"), c2t("STnc"), c2t("NC24"));
                list2.putObject(c2t("SCnc"), descriptor15);
                descriptor16.putEnumerated(c2t("ncTp"), c2t("STnc"), c2t("NC24"));
                list2.putObject(c2t("SCnc"), descriptor16);
                descriptor17.putEnumerated(c2t("ncTp"), c2t("STnc"), c2t("NC22"));
                list2.putObject(c2t("SCnc"), descriptor17);
                descriptor2.putList(c2t("ovNC"), list2);
                descriptor2.putBoolean(c2t("ovCM"), ovCM);
                descriptor2.putBoolean(c2t("ovCW"), ovCW);
                descriptor2.putBoolean(c2t("ovCU"), ovCU);
                descriptor2.putBoolean(c2t("ovSF"), ovSF);
                descriptor2.putBoolean(c2t("ovCB"), ovCB);
                descriptor2.putString(c2t("ovSN"), ovSN);
                descriptor.putObject(s2t("using"), s2t("SaveForWeb"), descriptor2);
                executeAction(s2t("export"), descriptor, DialogModes.NO)
            }
        }

    })();

} else {
    alert('Close all files before running this script');
}

 

 

Likes

translate

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