Skip to main content
Participant
May 16, 2007
Question

Script to automatically make a stack with a RAW+jpg pair of images

  • May 16, 2007
  • 15 replies
  • 2998 views
While on my last trip, I accidently setup my camera to take Raw + small jpg. No big deal, that isn't too much memory, so I didn't really worry about it. When I got home, the jpg files were copied to my hard drive along with the raw files. So, I went to delete the jpgs and I realized something. Bridge runs very fast when it's drawing thumbnails and previews of small jpg images. I got to thinking. Wouldn't it be cool to make a script that would take your raw+jpg from the camera and convert each pair into a stack with the jpg on top. This would enable bridge to run much more quickly since it wouldn't need to render all those raw image thumbs and previews.

Hmmm....now where to start....I looked around at the scripting language for photoshop. since I have written a little bit of javascript, I thought I would start there, but I can't find where the stack property is kept in metadata or the DOM.

Any ideas of where I might turn from here?
This topic has been closed for replies.

15 replies

Stephen Marsh
Community Expert
Community Expert
April 22, 2021

A little Googling:

 

my-abobe-scripting

autostack.jsx

 

 

/*
.--------------------------------------------------------------------------.
|    Software: Auto stacking files                                         |
|     Version: 0.35                                                        |
|        Site: http://code.google.com/p/my-abobe-scripting/                |
| Description: This script enable auto stacking files by name              |
| -------------------------------------------------------------------------|
|     Admin: Tyzhnenko Dmitry (project admininistrator)                    |
|   Authors: Tyzhnenko Dmitry t.dmitry@gmail.com                           |
|   Founder: Tyzhnenko Dmitry  (original founder)                          |
| Copyright (c) 2009-2011, Tyzhnenko Dmitry                                |
| -------------------------------------------------------------------------|
|   License: Distributed under the General Public License v3 (GPLv3)       |
|            http://www.gnu.org/licenses/gpl.html                          |
| This program is distributed in the hope that it will be useful - WITHOUT |
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    |
| FITNESS FOR A PARTICULAR PURPOSE.                                        |
'--------------------------------------------------------------------------'
*/

/* 
@@@START_XML@@@ 
<?xml version="1.0" encoding="UTF-8"?> 
<ScriptInfo xmlns:dc="http://purl.org/dc/elements/1.1/" xml:lang="en_US"> 
     <dc:title>Auto stacking files</dc:title> 
     <dc:description>This script enable auto stacing files by name function</dc:description> 
</ScriptInfo> 
@@@END_XML@@@ 
*/

function AutomaticStackingFiles() 
{ 
	/** 
	The context in which this snippet can run; Bridge must be running. 
	@type String 
	*/ 
	//this.requiredContext = "\tAdobe Bridge CS4 must be running.\n\tExecute against Bridge CS4 as the Target.\n"; 
	this.requiredContext = "\tAdobe Bridge CS4 must be running.\n\tExecute against Bridge CS4 as the Target.\n"; 
	$.level = 0; // Debugging level 

	this.version = "0.35"; 
	this.author = "Tyzhenenko Dmitry"; 

	/** 
	The unique identifier for the new menu item command 
	@type String 
	*/ 
	//this.menuID = "AutoStackFiles"; 
	this.menuCommandID = "GoAutoStackingFiles"; 

} 

function RunAutoStacking() 
{ 
	var doc = app.document; 
	//var thumb = doc.thumbnail; 
	//var vthumb = doc.visibleThumbnails; 
	var currSort = doc.sorts; 

	$.writeln("Start stacking");

	function StackPhoto() 
	{ 
		doc.chooseMenuItem('submenu/Stack'); 
		doc.chooseMenuItem('StackGroup'); 
	} 

	function CollapseStacks() 
	{ 
		doc.chooseMenuItem('submenu/Stack'); 
		doc.chooseMenuItem('CollapseAllStacks'); 
	} 

	function getFileExt( t) 
	{ 
		var dot = t.name.lastIndexOf ('.'); 
		return t.name.substr(dot,t.name.length); 
	} 

	function getFileName( t) 
	{ 
		var dot = t.name.lastIndexOf ('.'); 
		return t.name.substr(0, dot); 
	} 

	

	var SortObj = {}; 
	SortObj.name = "name"; 
	SortObj.type = "string"; 
	SortObj.reverse = false; 
	var SortsArray = []; 
	SortsArray.push(SortObj); 
	doc.sorts = SortsArray; 

	var iteration = 0 
	var stop = false;
	while (true)
	{
		$.writeln("= ");
		$.writeln("= While iteration  - "+ iteration.toString());
		if (stop) 
		{
			$.writeln("!!! Need to stop WHILE");
			break;
		}
		var vthumbs = doc.visibleThumbnails;
		$.writeln("= Total thumbs - " + doc.visibleThumbnails.length.toString());

		for ( i in vthumbs)
		{
			CollapseStacks(); 
			doc.deselectAll(); 
			doc.reveal(vthumbs[i]);
			if ( vthumbs.length == parseInt(i)+1)
			{
				$.writeln("!!! LAST iteration");
				stop = true;
				break;
			}
			$.writeln("== First name - " + vthumbs[i].name);
			$.writeln("== Next name - " + vthumbs[parseInt(i)+1].name);		
			$.writeln("== Last name - " + vthumbs[vthumbs.length-1].name);
			$.writeln("==");
			if ( getFileName( vthumbs[i] ) == getFileName( vthumbs[parseInt(i)+1]) ) 
			{
				doc.select(vthumbs[i]);
				$.writeln("=== Add to select - " + vthumbs[i].name);
				doc.select(vthumbs[parseInt(i)+1]);
				$.writeln("=== Add to select - " + vthumbs[parseInt(i)+1].name);		
				$.writeln("=== Stacking");
				StackPhoto(); 
				break;
			}
		}
		iteration++;
	}
	doc.sorts = currSort; 
	CollapseStacks(); 
	delete currSort; 
	delete vthumb; 
	delete thumb; 
	delete doc; 
	$.writeln("Finish stacking");
} 

AutomaticStackingFiles.prototype.run = function() 
{ 
	var retval = true; 
	if(!this.canRun()) { 
		retval = false; 
		return retval; 
	} 
	//app.document.chooseMenuItem('submenu/Stack'); 
	var AutoStackCommand = new MenuElement("command", "Auto stacking", "at the beginning of submenu/Stack"); 
	AutoStackCommand.onSelect = function(m) 
	{ 
		//alert('start'); 
		RunAutoStacking(); 
		//alert('stop'); 
	} 
} 

AutomaticStackingFiles.prototype.canRun = function() 
{ 
	// Must run in Bridge 
	if(BridgeTalk.appName == "bridge") 
	{ 
		// Stop the menu element from being added again if the snippet has already run 
		if(MenuElement.find(this.menuCommandID)) 
		{ 
			$.writeln("ERROR:: Menu element from AutoStackFiles already exists!\nRestart Bridge to run this snippet again."); 
			return false; 
		} 
	return true; 
	} 
	// Fail if these preconditions are not met. 
	// Bridge must be running, 
	// The menu must not already exist. 
	$.writeln("ERROR:: Cannot run AutomaticStackingFiles"); 
	$.writeln(this.requiredContext); 
	return false; 
} 

if(typeof(AutomaticStackingFiles_unitTest) == "undefined") { 
    new AutomaticStackingFiles().run(); 
}

 

Stephen Marsh
Community Expert
Community Expert
April 22, 2021

Not sure if this helps or not:

 

// https://forums.adobe.com/thread/738964
#target bridge     
   if( BridgeTalk.appName == "bridge" ) {    
AutoStack = MenuElement.create("command", "Auto Stack", "at the beginning of submenu/Stack", "zx1");  
}  
AutoStack.onSelect = function () {   
   stackEm();  
   }  
function stackEm(){  
app.document.sorts = [{ name:"name",type:"string", reverse:false}];   
var jpgs = Folder(app.document.presentationPath).getFiles ("*.jpg");  
app.document.deselectAll();  
for(var a in jpgs){  
var Name = decodeURI(jpgs[a].name).replace(/\.[^\.]+$/, '');  
var stacks = Folder(app.document.presentationPath).getFiles(Name+".*");  
if(stacks.length < 2) continue;  
for(var z in stacks){ app.document.select(new Thumbnail(stacks[z]));}  
StackFiles();  
app.document.deselectAll();  
}  
function StackFiles(){  
app.document.chooseMenuItem('submenu/Stack');   
app.document.chooseMenuItem('StackGroup');  
    }  
}  
Participating Frequently
March 19, 2009
update to 0.35
fix CS4 Bridge bug

Please who can do, test script with CS3 Bridge. I nave't CS3 now :(

http://code.google.com/p/my-abobe-scripting/source/browse/trunk/autostack.jsx
Participating Frequently
January 13, 2009
I have created project in google code.

All can try get script from this url

http://code.google.com/p/my-abobe-scripting/source/browse/trunk/autostack.jsx
Participating Frequently
January 12, 2009
Version with some changes.<br />Try fix some bug.<br />Try increase speed.<br /><br />If you found some bug or make changes or fix, please post it to this forum.<br /><br />-== [start of script] ==--<br /><br />///////////////////<br />/// Name: Auto stacking files<br />/// Description: This script enable auto stacking files by name<br />/// Author: Tyzhnenko Dmitry<br />/// E-mail: t.dmitry@gmail.com<br />/// Version: 0.32<br />///////////////////<br /><br />/*<br />@@@START_XML@@@<br /><?xml version="1.0" encoding="UTF-8"?><br /><ScriptInfo xmlns:dc="http://purl.org/dc/elements/1.1/" xml:lang="en_US"><br /> <dc:title>Auto stacking files</dc:title><br /> <dc:description>This script enable auto stacing files by name function</dc:description><br /></ScriptInfo><br />@@@END_XML@@@<br />*/<br /><br />function AutomaticStackingFiles()<br />{<br /> /**<br /> The context in which this snippet can run; Bridge must be running.<br /> @type String<br /> */<br /> this.requiredContext = "\tAdobe Bridge CS3 must be running.\n\tExecute against Bridge CS3 as the Target.\n";<br /> $.level = 1; // Debugging level<br /> <br /> this.version = "0.32";<br /> this.author = "Tyzhenenko Dmitry";<br /> <br /> /**<br /> The unique identifier for the new menu item command<br /> @type String<br /> */<br /> //this.menuID = "AutoStackFiles"; <br /> this.menuCommandID = "GoAutoStackingFiles";<br /><br />}<br /><br />function RunAutoStacking()<br />{<br /> var doc = app.document;<br /> var thumb = doc.thumbnail;<br /> var vthumb = doc.visibleThumbnails;<br /> var currSort = doc.sorts;<br /> <br /><br /> function StackPhoto()<br /> {<br /> doc.chooseMenuItem('submenu/Stack');<br /> doc.chooseMenuItem('StackGroup');<br /> }<br /><br /> function CollapseStacks()<br /> {<br /> doc.chooseMenuItem('submenu/Stack');<br /> doc.chooseMenuItem('CollapseAllStacks');<br /> }<br /><br /> function getFileExt( t)<br /> {<br /> var dot = t.name.lastIndexOf ('.');<br /> return t.name.substr(dot,t.name.length);<br /> }<br /><br /> function getFileName( t)<br /> {<br /> var dot = t.name.lastIndexOf ('.');<br /> return t.name.substr(0, dot);<br /> }<br /><br /> CollapseStacks();<br /> <br /> var SortObj = {}; <br /> SortObj.name = "name";<br /> SortObj.type = "string";<br /> SortObj.reverse = false;<br /> var SortsArray = [];<br /> SortsArray.push(SortObj);<br /> doc.sorts = SortsArray;<br /><br /> for (var len = 0; len < vthumb.length; len++ )<br /> {<br /> doc.deselectAll();<br /> doc.select(vthumb[len]);<br /> doc.reveal(vthumb[len]);<br /> for ( var k = len+1; k < vthumb.length; k++ )<br /> {<br /> //alert(k);<br /> if ( getFileName( vthumb[len] ) == getFileName( vthumb) ) <br /> doc.select(vthumb);<br /> else <br /> {<br /> if (doc.selectionLength > 1) <br /> StackPhoto();<br /> break;<br /> }<br /> if (k == vthumb.length-1)<br /> {<br /> if (doc.selectionLength > 1)<br /> StackPhoto();<br /> }<br /> <br /> //if (doc.selectionLength > 1) <br /> // StackPhoto();<br /> }<br /> //delete vthumb;<br /> //var <br /> //vthumb = @doc.visibleThumbnails;<br /> }<br /><br /> doc.sorts = currSort;<br /> doc.reveal(doc.visibleThumbnails[0]);<br /><br /> delete currSort;<br /> delete vthumb;<br /> delete thumb;<br /> delete doc;<br /> <br />}<br /><br />AutomaticStackingFiles.prototype.run = function()<br />{<br /> var retval = true;<br /> if(!this.canRun()) {<br /> retval = false; <br /> return retval;<br /> }<br /> //app.document.chooseMenuItem('submenu/Stack');<br /> var AutoStackCommand = new MenuElement("command", "Auto stacking", "at the beginning of submenu/Stack", );<br /> AutoStackCommand.onSelect = function(m)<br /> {<br /> //alert('start');<br /> RunAutoStacking(); <br /> //alert('stop');<br /> }<br />}<br /><br />AutomaticStackingFiles.prototype.canRun = function()<br />{ <br /> // Must run in Bridge <br /> if(BridgeTalk.appName == "bridge") <br /> {<br /> // Stop the menu element from being added again if the snippet has already run<br /> if(MenuElement.find(this.menuCommandID))<br /> {<br /> $.writeln("ERROR:: Menu element from AutoStackFiles already exists!\nRestart Bridge to run this snippet again.");<br /> return false;<br /> }<br /> return true;<br /> }<br /> // Fail if these preconditions are not met. <br /> // Bridge must be running,<br /> // The menu must not already exist.<br /> $.writeln("ERROR:: Cannot run AutomaticStackingFiles");<br /> $.writeln(this.requiredContext);<br /> return false;<br />}<br /><br />if(typeof(AutomaticStackingFiles_unitTest) == "undefined") {<br /> new AutomaticStackingFiles().run();<br />}<br /><br />-== [end of script] ==--
Participating Frequently
December 15, 2008
Hello, David.

Please, can you post changes which you do, or send it to my email.
thx.
Participating Frequently
November 30, 2008
Thanks!

Good Luck.
______
My Si tes
Participant
November 18, 2008
Hello again Dmitry,
I managed to get the script working myself, and it works brilliantly. Thank you very much - you've solve a workflow problem that has been bugging me for several years.
Best
David Peart
Participant
November 18, 2008
Hello Dmitry,
I've copied and saved your script but it doesn't seem to work... there are some issues with closing parenthesis, and a variable it doesn't recognise (currSort).
Any chance you can have a look at it because if it works, you will be doing me an enormous favour.
David
Participating Frequently
August 28, 2008
Save this and use it :)<br />This script stack all similar files by name with out extension.<br /><br />--= begin of 'autostack.jsx' file =--<br />///////////////////<br />/// Name: Auto stacking files<br />/// Description: This script enable auto stacking files by name<br />/// Author: Tyzhnenko Dmitry<br />/// E-mail: t.dmitry@gmail.com<br />/// Version: 0.3<br />///////////////////<br /><br />/*<br />@@@START_XML@@@<br /><?xml version="1.0" encoding="UTF-8"?><br /><ScriptInfo xmlns:dc="http://purl.org/dc/elements/1.1/" xml:lang="en_US"><br /> <dc:title>Auto stacking files</dc:title><br /> <dc:description>This script enable auto stacing files by name function</dc:description><br /></ScriptInfo><br />@@@END_XML@@@<br />*/<br /><br />function AutomaticStackingFiles()<br />{<br /> /**<br /> The context in which this snippet can run; Bridge must be running.<br /> @type String<br /> */<br /> this.requiredContext = "\tAdobe Bridge CS3 must be running.\n\tExecute against Bridge CS3 as the Target.\n";<br /> $.level = 1; // Debugging level<br /> <br /> this.version = "0.3";<br /> this.author = "Tyzhenenko Dmitry";<br /> <br /> /**<br /> The unique identifier for the new menu item command<br /> @type String<br /> */<br /> //this.menuID = "AutoStackFiles"; <br /> this.menuCommandID = "GoAutoStackingFiles";<br /><br />}<br /><br />function RunAutoStacking()<br />{<br /> var doc = app.document;<br /> var thumb = doc.thumbnail;<br /> var vthumb = doc.visibleThumbnails;<br /> var currSort = doc.sorts;<br /><br /> var stacks_arr = new Array;<br /><br /> function StackPhoto()<br /> {<br /> doc.chooseMenuItem('submenu/Stack');<br /> doc.chooseMenuItem('StackGroup');<br /> }<br /><br /> function getFileExt( t)<br /> {<br /> var dot = t.name.lastIndexOf ('.');<br /> return t.name.substr(dot,t.name.length);<br /> }<br /><br /> function getFileName( t)<br /> {<br /> var dot = t.name.lastIndexOf ('.');<br /> return t.name.substr(0, dot);<br /> }<br /><br /> var SortObj = {}; <br /> SortObj.name = "name";<br /> SortObj.type = "string";<br /> SortObj.reverse = false;<br /> var SortsArray = [];<br /> SortsArray.push(SortObj);<br /> doc.sorts = SortsArray;<br /><br /> for (var len = 0; len < vthumb.length; len++ )<br /> {<br /> doc.deselectAll();<br /> doc.select(vthumb[len]);<br /> for ( var k = len+1; k < vthumb.length; k++ )<br /> {<br /> //alert(k);<br /> if ( getFileName( vthumb[len] ) == getFileName( vthumb) ) <br /> doc.select(vthumb);<br /> else <br /> {<br /> if (doc.selectionLength > 1) <br /> StackPhoto();<br /> break;<br /> }<br /> <br /> if (doc.selectionLength > 1) <br /> StackPhoto();<br /> }<br /> vthumb = doc.visibleThumbnails;<br /> }<br /><br /> doc.sorts = currSort;<br /><br />}<br /><br />AutomaticStackingFiles.prototype.run = function()<br />{<br /> var retval = true;<br /> if(!this.canRun()) {<br /> retval = false; <br /> return retval;<br /> }<br /> //app.document.chooseMenuItem('submenu/Stack');<br /> var AutoStackCommand = new MenuElement("command", "Auto stacking", "at the beginning of submenu/Stack", );<br /> AutoStackCommand.onSelect = function(m)<br /> {<br /> RunAutoStacking(); <br /> }<br />}<br /><br />AutomaticStackingFiles.prototype.canRun = function()<br />{ <br /> // Must run in Bridge <br /> if(BridgeTalk.appName == "bridge") <br /> {<br /> // Stop the menu element from being added again if the snippet has already run<br /> if(MenuElement.find(this.menuCommandID))<br /> {<br /> $.writeln("ERROR:: Menu element from AutoStackFiles already exists!\nRestart Bridge to run this snippet again.");<br /> return false;<br /> }<br /> return true;<br /> }<br /> // Fail if these preconditions are not met. <br /> // Bridge must be running,<br /> // The menu must not already exist.<br /> $.writeln("ERROR:: Cannot run AutomaticStackingFiles");<br /> $.writeln(this.requiredContext);<br /> return false;<br />}<br /><br />if(typeof(AutomaticStackingFiles_unitTest) == "undefined") {<br /> new AutomaticStackingFiles().run();<br />}<br /><br />--= end of 'autostack.jsx' file =--
Known Participant
April 22, 2021

Hi @T_dimitry,

 

Do you still have this code formatted in a document?  I'm trying to format paste in a document I can put in the presets folder.

 

Thanks!