Skip to main content
Known Participant
October 24, 2011
Question

Batch process RAW exposures, please help!

  • October 24, 2011
  • 13 replies
  • 5573 views

Hello, I'm new to photoshop scripting for windows, and I was wondering if anyone knew how to batch process a folder of raw files, change the the raw's exposure, and save as jpg to another folder, based on a condition within the file's name, then close the opended jpg  document.

My goal is to have a script that extracts the correct exposures from sets of three bracketed raw files, which I usually have seperated by 2 EV's.  So for example, say I have a folder Called Batch Processing on the C drive, and I have two folders,

C:\Batch Processing\JPG

C:\Batch Processing\RAW

and in the RAW folder I have some files called,

Image_01_E01.cr2

Image_01_E02.cr2

Image_01_E03.cr2

If the file has "_E01" at the end, I want to open that raw file, change the exposure to -4, save the file with the same name, except the last 4 characters, and add some number to the end, so for example, it would end up being "Image_01" + "_E01".  This would end up being saved to the JPG folder. Then open up the same file, change the exposure to -2 and save as "Image_01" + "_E02".

To make this post short, here is the conversion table I'm trying to achieve -

Image_01_E01.cr2 -> Image_01_E01.jpg Exposure = -4

Image_01_E01.cr2 -> Image_01_E02.jpg Exposure = -2

Image_01_E02.cr2 -> Image_01_E03.jpg Exposure = -2

Image_01_E02.cr2 -> Image_01_E04.jpg Exposure = 0

Image_01_E02.cr2 -> Image_01_E05.jpg Exposure = 2

Image_01_E03.cr2 -> Image_01_E06.jpg Exposure = 2

Image_01_E03.cr2 -> Image_01_E07.jpg Exposure = 4

After that, close all open files. Then, if there is another set of raws, repeat for them as well. For example -

Image_02_E01.cr2 -> Image_02_E01.jpg Exposure = -4

Image_02_E01.cr2 -> Image_02_E02.jpg Exposure = -2

Image_02_E02.cr2 -> Image_02_E03.jpg Exposure = -2

Image_02_E02.cr2 -> Image_02_E04.jpg Exposure = 0

Image_02_E02.cr2 -> Image_02_E05.jpg Exposure = 2

Image_02_E03.cr2 -> Image_02_E06.jpg Exposure = 2

Image_02_E03.cr2 -> Image_02_E07.jpg Exposure = 4

So basically this script would take 3 raws seperated by 2 EV's and extract 7 exposures, seperated by 2 EV's.  I've done this manually, and merged them to hdr, and the results are actually pretty decent. 

I tried doing this with actions and batch processing, but I had to have everything seperated in individual folders like E01, E02, etc. and I had to make an action for each step in the process.

I know this is probably a lot to ask, but I think it can be done, and I would of course credit the person in the script for helping.

Thanks in advance!

This topic has been closed for replies.

13 replies

Ian___Author
Known Participant
October 29, 2011

Hey Paul, I'm not sure if its your script, or if its because of the xmp settings file that's created by the raw files, but some of the exposures that are created are the same. I think the script is saving the first exposure values choosen for each file.

For example the exposures are saved as follows -

Image_01_E01.cr2 -> Image_01_E01.jpg Exposure = -4

Image_01_E01.cr2 -> Image_01_E02.jpg Exposure = -4

Image_01_E02.cr2 -> Image_01_E03.jpg Exposure = -2

Image_01_E02.cr2 -> Image_01_E04.jpg Exposure = -2

Image_01_E02.cr2 -> Image_01_E05.jpg Exposure = -2

Image_01_E03.cr2 -> Image_01_E06.jpg Exposure = 2

Image_01_E03.cr2 -> Image_01_E07.jpg Exposure = 2

Maybe each xmp file has to be deleted after each jpg file is saved from the script. Please let me know what your thoughts are on this as soon as you can, thanks in advance, - Ian

Paul Riggott
Inspiring
October 29, 2011

Ah, I found a couple of errors in the code which have now been corrected, could you try this now....

#target bridge  
   if( BridgeTalk.appName == "bridge" ) { 
CR2JPG = MenuElement.create("command", "CR2 to Seven JPGs", "at the end of Tools");
}
CR2JPG.onSelect = function () {
var progressBar = function(title) {
var w = new Window( 'palette', ' '+title, {x:0, y:0, width:340, height:60} ),
pb = w.add( 'progressbar', {x:20, y:12, width:300, height:12}, 0, 100 ),
st = w.add( 'statictext', {x:10, y:36, width:320, height:20}, '' );
st.justify = 'center';
w.center();

this.reset = function( msg,maxValue ) {
st.text = msg;
pb.value = 0;
pb.maxvalue = maxValue||0;
pb.visible = !!maxValue;
w.show();
};
this.hit = function() { ++pb.value; };
this.hide = function() { w.hide(); };
this.close = function() { w.close(); };
this.show = function() { w.show(); };
this.update = function() { w.update(); };
this.layout = function() { w.layout.layout(); };
};
function doPbar(){
pBar.hit();
pBar.hide();
pBar.show();
    }
var count = 0;
var Path = Folder(app.document.presentationPath);
var group1 = Path.getFiles(/\e01.cr2$/i);
var group2 = Path.getFiles(/\e02.cr2$/i);
var group3 = Path.getFiles(/\e03.cr2$/i);
count += group1.length;
count += group2.length;
count += group3.length;
var jpgFolder = Folder(Path+"/JPG");
if(!jpgFolder.exists) jpgFolder.create();
if(count <1) return;
var pBar = new progressBar("CR2 to Seven JPGs");
pBar.reset("Processing E01 Files", (group1.length*2));
for(var a in group1){
var thumb = new Thumbnail(group1);
var Name = decodeURI(group1
.name).replace(/\.[^\.]+$/, '');
Name = Name.replace(/e01$/i,'');
group1Exposure = setEV(group1
,-4);
var BM = createBM(thumb);
var exportFile = new File( jpgFolder + "/" + Name + "E01.jpg" );
BM.exportTo( exportFile,  100);
doPbar();
setEV(group1
,-2);
BM = createBM(thumb);
var exportFile = new File( jpgFolder + "/" + Name + "E02.jpg" );
BM.exportTo( exportFile,  100);
setEV(group1
,group1Exposure);
doPbar();
    }
pBar.reset("Processing E02 Files", (group2.length*3));
for(var b in group2){
var thumb = new Thumbnail(group2);
var Name = decodeURI(group2.name).replace(/\.[^\.]+$/, '');
Name = Name.replace(/e02$/i,'');
group2Exposure = setEV(group2,-2);
var BM = createBM(thumb);
var exportFile = new File( jpgFolder + "/" + Name + "E03.jpg" );
BM.exportTo( exportFile,  100);
doPbar();
setEV(group2,0);
BM = createBM(thumb);
var exportFile = new File( jpgFolder + "/" + Name + "E04.jpg" );
BM.exportTo( exportFile,  100);
doPbar();
setEV(group2,2);
BM = createBM(thumb);
var exportFile = new File( jpgFolder + "/" + Name + "E05.jpg" );
BM.exportTo( exportFile,  100);
setEV(group2,group2Exposure);
doPbar();
    }
pBar.reset("Processing E03 Files", (group3.length*2));
for(var c in group3){
var thumb = new Thumbnail(group3);
var Name = decodeURI(group3.name).replace(/\.[^\.]+$/, '');
Name = Name.replace(/e03$/i,'');
group2Exposure = setEV(group3,2);
var BM = createBM(thumb);
var exportFile = new File( jpgFolder + "/" + Name + "E06.jpg" );
BM.exportTo( exportFile,  100);
doPbar();
setEV(group3,4);
BM = createBM(thumb);
var exportFile = new File( jpgFolder + "/" + Name + "E07.jpg" );
BM.exportTo( exportFile,  100);
setEV(group3,group2Exposure);
doPbar();
    }
pBar.close();
function setEV(thumb,evValue){
var Name = decodeURI(new Thumbnail(thumb).spec.name).replace(/\.[^\.]+$/, '');
var file = new File(new Thumbnail(thumb).spec.path +"/" +Name +".xmp");
try{
if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
  if(file.exists){
     file.open('r');
     file.encoding = "UTF8";
     file.lineFeed = "unix";
     file.open("r", "TEXT", "????");
     var xmpStr = file.read();
     file.close();
     }else{
         var xmpStr='';
         }
     var xmp = new XMPMeta( xmpStr );
    var exposureValue = xmp.getProperty(XMPConst.NS_CAMERA_RAW, "Exposure");
    xmp.deleteProperty(XMPConst.NS_CAMERA_RAW, "Exposure");
    xmp.setProperty(XMPConst.NS_CAMERA_RAW, "Exposure",Number(evValue));
     file.open('w');
     file.encoding = "UTF8";
     file.lineFeed = "unix";
     file.write( xmp.serialize() );
     file.close();
     if(exposureValue  == undefined) exposureValue = 0;
     }catch(e){alert(e+"-"+e.line);}
     return exposureValue;
};

function createBM(thumb){
var sourceBitmap = undefined;
app.synchronousMode = true;
sourceBitmap = thumb.core.fullsize.fullsize;
app.synchronousMode = false;
sourceBitmap = sourceBitmap.rotate(thumb.rotation);
return sourceBitmap;
    }
};

Ian___Author
Known Participant
October 25, 2011

Oh, BTW, I was also wondering how you would batch those resulting exposures using Merge to HDR Pro with default settings, into hdr files, with the corresponding file names, so that the files would end up being called Image_01.hdr, Image_02.hdr, etc. in a folder called HDR. The path would be C:\Batch Processing\HDR

Im sure this would be pretty tricky as well, but its probably nothing your mighty scripting skills couldn't handle. 

Paul Riggott
Inspiring
October 25, 2011

Hi Ian, I have never worked with HDR, Mike has done some work on these though and might chip in.

http://forums.adobe.com/thread/653485?tstart=0

As for running droplets, that would not be possible with the script above as everything is done in Bridge, Photoshop is not involved in any way.

I don't think you can add an attachment but you can add a link to somewhere where it can be downloaded.

Paul Riggott
Inspiring
October 24, 2011

Hi Ian, this might be better done in Bridge. Could you let me know what version of Photoshop you have as it would require CS4 or better to do this in Bridge.

Paul Riggott
Inspiring
October 24, 2011

Ok I am assuming you have CS4 or better...

Copy and paste the script into ExtendScript Toolkit
This gets installed with Photoshop and can be found:-
PC: C:\Program Files\Adobe\Adobe Utilities
MAC: <hard drive>/Applications/Utilities/Adobe Utilities

Start Bridge
PC: Edit - Preferences - Startup Scripts
Mac: Adobe Bridge menu - Preferences - Startup Scripts
At the bottom click the "Reveal Button" this will open the folder where the script should be saved.
Close and restart Bridge.
Accept the new script.

To use:-
Navigate to the folder with your CR2 files, then Tools - "CR2 to Seven JPGs"
Go get a coffee.

#target bridge  
   if( BridgeTalk.appName == "bridge" ) { 
CR2JPG = MenuElement.create("command", "CR2 to Seven JPGs", "at the end of Tools");
}
CR2JPG.onSelect = function () {
var progressBar = function(title) {
var w = new Window( 'palette', ' '+title, {x:0, y:0, width:340, height:60} ),
pb = w.add( 'progressbar', {x:20, y:12, width:300, height:12}, 0, 100 ),
st = w.add( 'statictext', {x:10, y:36, width:320, height:20}, '' );
st.justify = 'center';
w.center();

this.reset = function( msg,maxValue ) {
st.text = msg;
pb.value = 0;
pb.maxvalue = maxValue||0;
pb.visible = !!maxValue;
w.show();
};
this.hit = function() { ++pb.value; };
this.hide = function() { w.hide(); };
this.close = function() { w.close(); };
this.show = function() { w.show(); };
this.update = function() { w.update(); };
this.layout = function() { w.layout.layout(); };
};
function doPbar(){
pBar.hit();
pBar.hide();
pBar.show();
    }
var count = 0;
var Path = Folder(app.document.presentationPath);
var group1 = Path.getFiles(/\e01.cr2$/i);
var group2 = Path.getFiles(/\e02.cr2$/i);
var group3 = Path.getFiles(/\e03.cr2$/i);
count += group1.length;
count += group2.length;
count += group3.length;
var jpgFolder = Folder(Path+"/JPG");
if(!jpgFolder.exists) jpgFolder.create();
if(count <1) return;
var pBar = new progressBar("CR2 to Seven JPGs");
pBar.reset("Processing E01 Files", (group1.length*2));
for(var a in group1){
var thumb = new Thumbnail(group1);
var Name = decodeURI(group1
.name).replace(/\.[^\.]+$/, '');
Name = Name.replace(/e01$/i,'');
group1Exposure = setEV(group1
,-4);
var BM = createBM(thumb);
var exportFile = new File( jpgFolder + "/" + Name + "E01.jpg" );
BM.exportTo( exportFile,  100);
doPbar();
setEV(group1
,-2);
BM = createBM(thumb);
var exportFile = new File( jpgFolder + "/" + Name + "E02.jpg" );
BM.exportTo( exportFile,  100);
setEV(group1
,group1Exposure);
doPbar();
    }
pBar.reset("Processing E02 Files", (group2.length*3));
for(var b in group2){
var thumb = new Thumbnail(group2);
var Name = decodeURI(group2.name).replace(/\.[^\.]+$/, '');
Name = Name.replace(/e02$/i,'');
group2Exposure = setEV(group2,-2);
var BM = createBM(thumb);
var exportFile = new File( jpgFolder + "/" + Name + "E03.jpg" );
BM.exportTo( exportFile,  100);
doPbar();
setEV(group2,-2);
BM = createBM(thumb);
var exportFile = new File( jpgFolder + "/" + Name + "E04.jpg" );
BM.exportTo( exportFile,  100);
doPbar();
setEV(group2,0);
BM = createBM(thumb);
var exportFile = new File( jpgFolder + "/" + Name + "E05.jpg" );
setEV(group2,2);
BM = createBM(thumb);
BM.exportTo( exportFile,  100);
setEV(group2,group2Exposure);
doPbar();
    }
pBar.reset("Processing E03 Files", (group3.length*2));
for(var c in group3){
var thumb = new Thumbnail(group3);
var Name = decodeURI(group3.name).replace(/\.[^\.]+$/, '');
Name = Name.replace(/e03$/i,'');
group2Exposure = setEV(group3,2);
var BM = createBM(thumb);
var exportFile = new File( jpgFolder + "/" + Name + "E06.jpg" );
BM.exportTo( exportFile,  100);
doPbar();
setEV(group3,2);
BM = createBM(thumb);
var exportFile = new File( jpgFolder + "/" + Name + "E07.jpg" );
setEV(group3,4);
BM = createBM(thumb);
BM.exportTo( exportFile,  100);
setEV(group3,group2Exposure);
doPbar();
    }
pBar.close();
function setEV(thumb,evValue){
var Name = decodeURI(new Thumbnail(thumb).spec.name).replace(/\.[^\.]+$/, '');
var file = new File(new Thumbnail(thumb).spec.path +"/" +Name +".xmp");
try{
if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
  if(file.exists){
     file.open('r');
     file.encoding = "UTF8";
     file.lineFeed = "unix";
     file.open("r", "TEXT", "????");
     var xmpStr = file.read();
     file.close();
     }else{
         var xmpStr='';
         }
     var xmp = new XMPMeta( xmpStr );
    var exposureValue = xmp.getProperty(XMPConst.NS_CAMERA_RAW, "Exposure");
    xmp.deleteProperty(XMPConst.NS_CAMERA_RAW, "Exposure");
    xmp.setProperty(XMPConst.NS_CAMERA_RAW, "Exposure",Number(evValue));
     file.open('w');
     file.encoding = "UTF8";
     file.lineFeed = "unix";
     file.write( xmp.serialize() );
     file.close();
     if(exposureValue  == undefined) exposureValue = 0;
     }catch(e){alert(e+"-"+e.line);}
     return exposureValue;
};

function createBM(thumb){
var sourceBitmap = undefined;
app.synchronousMode = true;
sourceBitmap = thumb.core.fullsize.fullsize;
app.synchronousMode = false;
sourceBitmap = sourceBitmap.rotate(thumb.rotation);
return sourceBitmap;
    }
};

Ian___Author
Known Participant
October 25, 2011

WOW, thanks for the reply, I am using CS5. I'll definitely give this a try. My goal is to have everything dealing with hdr in droplets, whether they are scripts or actions. I'll have to break down this script and figure out how it works, because also plan on making different permutations of it, such as converting 9 exposures from 5 raws, or getting 3 exposures from a single raw. If you want, I can post a bracketing chart from excel I made, that has different conversion variations from raws. This chart is assuming that you can get +-4 EV for the exposure. How do you make an attachment here?

Thanks again for your help, -Ian