I am currently using this script I found elsewhere on Adobe forums. However, doing this function only will stack everything with the raw files on top. I am using a 5D MKIII now and Bridge CS4 can't generate the CR2 previews, so I need JPEGs to see what a file is for general editing. How do I get this stack script to put the JPEGS on top instead of the raw files?
(script originally posted by Paul Riggot in another forum)
#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');
Hopfully this should work now, I have now changed the sort order so the jpg is first...
#target bridge
if( BridgeTalk.appName == "bridge" ) {
AutoStack = MenuElement.create("command", "Auto Stack", "at the beginning of submenu/Stack", "zx1");
}
AutoStack.onSelect = function () {
app.document.sorts = [{ name:"name",type:"string", reverse:true}];
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]));}
app.document.chooseMenuItem('StackGroup');
app.document.deselectAll();
}
app.document.sorts = [{ name:"name",type:"string", reverse:false}];
}
Wow such a quick fix. Thanks!!! This works. This is a great supplement until I get CS5 or LR4.
The only problem is that bridge does not link file actions to all files in the stack
still have to click delete twice and use star ratings twice etc...
Are stacks natively all inclusive to file ratings and deletes or has the script changed that?
I wonder if you have time if you could test this script for me please?
What it does (tries to do) is to create JPGs from the raw files in the same folder as the CR2 (raw) files.
N.B. IT WILL OVERWRITE ANY JPGS IN THE SAME FOLDER IF THE NAMES MATCH!
So please try it on a folder with raw files only.
The idea being it might be quicker to generate jpegs from the embedded thumbnail rather than shoot both raw/jpg?
T.I.A.
#target bridge
if( BridgeTalk.appName == "bridge" ) {
AutoStackJpgs = MenuElement.create("command", "Create Stack JPGs", "at the beginning of submenu/Stack", "sj1");
}
AutoStackJpgs .onSelect = function () {
app.document.deselectAll();
var items = app.document.getSelection("crw,cr2,tiff,raw,rw2,dng,nef,orf,erf,mos,dcr,raf,srf,pef,x3f");
for (var a =0; a<items.length;a++){
var JPEG = new File(items[a].path.substr(0,items[a].path.lastIndexOf ('.'))+".jpg");
tempFile=new File(items[a].path);
var fileString='';
tempFile.open('r');
tempFile.encoding = 'BINARY';
fileString=tempFile.read();
tempFile.close();
for(var w =0;w<6;w++){
var startJpg=fileString.search(/\xFF\xD8\xFF/);
if(startJpg != -1){
if(testJPG()){
var endJpg = fileString.search(/\xFF\xD9/);
fileString = fileString.substr(0,endJpg+2);
JPEG.open('w');
JPEG.encoding = 'BINARY';
JPEG.write(fileString);
JPEG.close();
var newThumb = new Thumbnail(JPEG);
newThumb.rotation = items[a].rotation;
break;
}else{
fileString = fileString.substr(20);
continue;
}}}
function testJPG(){
var result=false;
fileString = fileString.substr(startJpg);
var endTest = fileString.search(/\xFF\xD9/);
if(endTest > 204800 ? result= true : result= false);
return result;
}
}
}
Yeah it works quite well! Tested on 24 RAWs totaling 630MB with their matching JPEGs totaling 201MB moved to another folder. The script generates %100 scale images, not just previews. It converted all the RAW images in ~8 seconds. The final size of the JPEG group after script processing is 51MB vs the 210MB from the camera JPEG. It is compressing them somewhat but at a micro-detail level which most would not notice. Color also shifts slightly, and contrast is slightly reduced. The quality/compression is comparable to selecting 9 or 10 quality instead of 12 in PS - a negligible difference.
Honestly, your script does a better job generating JPEGs from the RAW than the damn camera does since it only reduces detail at the slightest while compressing it to 1/4 the size overall. It is very handy! Now, if you can add a safety net to not overwrite currently existing JPEGs of the same name, you'd be golden. Its funny that it can generate %100 scale JPEGs that are nearly equal to the camera JPEGs, yet the CR2 format from the 5D MKIII isn't technically even supported in CS4. You just created a workaround for raw shooters with any version below CS5 that can use the script! I'm sure Adobes pocketbook will love you
lol
Thank you very much for the detailed report. I only have a 5D MK1 so didn't know if it would work with newer models.
The jpegs should be smaller as no metadata is being transfered from the raw file, I have added a check so that existing jpgs are not overwritten.
Hope it may be of use to you.
#target bridge
if( BridgeTalk.appName == "bridge" ) {
AutoStackJpgs = MenuElement.create("command", "Create Stack JPGs", "at the beginning of submenu/Stack", "sj1");
}
AutoStackJpgs .onSelect = function () {
app.document.deselectAll();
var items = app.document.getSelection("crw,cr2,tiff,raw,rw2,dng,nef,orf,erf,mos,dcr,raf,srf,pef,x3f");
for (var a =0; a<items.length;a++){
var JPEG = new File(items[a].path.substr(0,items[a].path.lastIndexOf ('.'))+".jpg");
if(JPEG.exists) continue;
tempFile=new File(items[a].path);
var fileString='';
tempFile.open('r');
tempFile.encoding = 'BINARY';
fileString=tempFile.read();
tempFile.close();
for(var w =0;w<6;w++){
var startJpg=fileString.search(/\xFF\xD8\xFF/);
if(startJpg != -1){
if(testJPG()){
var endJpg = fileString.search(/\xFF\xD9/);
fileString = fileString.substr(0,endJpg+2);
JPEG.open('w');
JPEG.encoding = 'BINARY';
JPEG.write(fileString);
JPEG.close();
var newThumb = new Thumbnail(JPEG);
newThumb.rotation = items[a].rotation;
break;
}else{
fileString = fileString.substr(20);
continue;
}}}
function testJPG(){
var result=false;
fileString = fileString.substr(startJpg);
var endTest = fileString.search(/\xFF\xD9/);
if(endTest > 204800 ? result= true : result= false);
return result;
}
}
}
Hi Paul!
I am starting to use Adobe Bridge now and I found your post was exactly my solution to my problem - I wanted to stack both the JPEG and RAW together.
I have two questions (which I will probably eventually find out, but I want to ask you first and search for my answer)
1) What line to do add this script to on the JSX file? Or is it a separate file that you add to the startup script folder (you make another .jsx file?)
2) If I have both the RAW and JPEG stacked, will me rating that stack effect both the JPEG and RAW (XML)?
Thank you so much!
Happy New Year,
Justin
Okay!
I just created a .jsx extension file with the code above (directly copied and pasted)
The directoy of the .jsx extension is:
C:\Users\(myuserrname)\AppData\Roaming\Adobe\Bridge CS5\Startup Scripts
Yes, I am using AdobeBridge CS5.
I have enabled the file via the start-up script preferences. When I restarted bridge it asked me if I wanted to use this script (clicked 'yes').
Also, I have named the script file, "stacking.jsx"
I have no idea what I am doing which doesn't allow the CR2 (canon RAW) and the jpgs to stack.
Thank you for everything,
Justin
-- Thank you about the rating tip as well ![]()
North America
Europe, Middle East and Africa
Asia Pacific