Hi,
what i'm trying to do is make an automated color correction.
first it needs to make a merge of all layers, then it needs to use the blur-> average filter. create a new curves adjustment layer and then i'm stuck... it needs to set the grey point using the middle eyedropper in the curves dialog.
this is what i have come up with so far, all by using the scriptlistner.
Ps i'm very new to all this so any help would be greatly appreciated
thank you !
Code: Select all// =======================================================
var idMk = charIDToTypeID( "Mk " );
var desc7 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref3 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
ref3.putClass( idLyr );
desc7.putReference( idnull, ref3 );
var idUsng = charIDToTypeID( "Usng" );
var desc8 = new ActionDescriptor();
var idNm = charIDToTypeID( "Nm " );
desc8.putString( idNm, "Dupe" );
var idLyr = charIDToTypeID( "Lyr " );
desc7.putObject( idUsng, idLyr, desc8 );
executeAction( idMk, desc7, DialogModes.NO );
// =======================================================
var idMrgV = charIDToTypeID( "MrgV" );
var desc9 = new ActionDescriptor();
var idDplc = charIDToTypeID( "Dplc" );
desc9.putBoolean( idDplc, true );
executeAction( idMrgV, desc9, DialogModes.NO );
// =======================================================
var idAvrg = charIDToTypeID( "Avrg" );
executeAction( idAvrg, undefined, DialogModes.NO );
// =======================================================
var idMk = charIDToTypeID( "Mk " );
var desc10 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref4 = new ActionReference();
var idAdjL = charIDToTypeID( "AdjL" );
ref4.putClass( idAdjL );
desc10.putReference( idnull, ref4 );
var idUsng = charIDToTypeID( "Usng" );
var desc11 = new ActionDescriptor();
var idNm = charIDToTypeID( "Nm " );
desc11.putString( idNm, "Correct CC" );
var idType = charIDToTypeID( "Type" );
var desc12 = new ActionDescriptor();
var idpresetKind = stringIDToTypeID( "presetKind" );
var idpresetKindType = stringIDToTypeID( "presetKindType" );
var idpresetKindDefault = stringIDToTypeID( "presetKindDefault" );
desc12.putEnumerated( idpresetKind, idpresetKindType, idpresetKindDefault );
var idCrvs = charIDToTypeID( "Crvs" );
desc11.putObject( idType, idCrvs, desc12 );
var idAdjL = charIDToTypeID( "AdjL" );
desc10.putObject( idUsng, idAdjL, desc11 );
executeAction( idMk, desc10, DialogModes.NO );
// =======================================================
?? select grey point in curves ??
// =======================================================
var idslct = charIDToTypeID( "slct" );
var desc27 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref9 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
ref9.putName( idLyr, "Dupe" );
desc27.putReference( idnull, ref9 );
var idMkVs = charIDToTypeID( "MkVs" );
desc27.putBoolean( idMkVs, false );
executeAction( idslct, desc27, DialogModes.NO );
// =======================================================
var idDlt = charIDToTypeID( "Dlt " );
var desc28 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref10 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref10.putEnumerated( idLyr, idOrdn, idTrgt );
desc28.putReference( idnull, ref10 );
executeAction( idDlt, desc28, DialogModes.NO );
Set gray point - curves
Set gray point - curves
I had a look at this after your first post. It requires the script to be able to work out the gamma correction for each channel.
That may be possible, however I didn't pursue it after a few test because this type of color correction suffers from subject failure i.e. Santa's red suit will cause this to over correct towards cyan.
That may be possible, however I didn't pursue it after a few test because this type of color correction suffers from subject failure i.e. Santa's red suit will cause this to over correct towards cyan.
Set gray point - curves
I gave this another go and here is what I came up with. The script below expects a 8bit RGB image.
Code: Select allvar doc = activeDocument;
doc.flatten();
var mainLayer = doc.activeLayer;
var filterLayer = mainLayer.duplicate ();
doc.activeLayer = filterLayer;
filterLayer.applyAverage();
var re = RegExp( '[123456789]+' );
var rValue = re.exec( doc.channels[0].histogram.toString() ).index/2;
var gValue = re.exec( doc.channels[1].histogram.toString() ).index/2;
var bValue = re.exec( doc.channels[2].histogram.toString() ).index/2;
var values = [ rValue, gValue, bValue ];
values = values.sort( function( a, b ){ return a < b } );
var targetValue = values[1];
var redGamma = Math.log( ( 255 / rValue ) ) / Math.log( ( 255 / targetValue ) );
var greenGamma = Math.log( ( 255 / gValue ) ) / Math.log( ( 255 / targetValue ) );
var blueGamma = Math.log( ( 255 / bValue ) ) / Math.log( ( 255 / targetValue ) );
// make the levels adjustment layer
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putClass( stringIDToTypeID( "adjustmentLayer" ) );
desc.putReference( stringIDToTypeID( "null" ), ref );
var typeDesc = new ActionDescriptor();
typeDesc.putClass( stringIDToTypeID( "type" ), stringIDToTypeID( "levels" ) );
desc.putObject( stringIDToTypeID( "using" ), stringIDToTypeID( "adjustmentLayer" ), typeDesc );
executeAction( stringIDToTypeID( "make" ), desc, DialogModes.NO );
//
var idsetd = charIDToTypeID( "setd" );
var desc7 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref5 = new ActionReference();
var idAdjL = charIDToTypeID( "AdjL" );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref5.putEnumerated( idAdjL, idOrdn, idTrgt );
desc7.putReference( idnull, ref5 );
var idT = charIDToTypeID( "T " );
var desc8 = new ActionDescriptor();
var idpresetKind = stringIDToTypeID( "presetKind" );
var idpresetKindType = stringIDToTypeID( "presetKindType" );
var idpresetKindCustom = stringIDToTypeID( "presetKindCustom" );
desc8.putEnumerated( idpresetKind, idpresetKindType, idpresetKindCustom );
var idAdjs = charIDToTypeID( "Adjs" );
var list1 = new ActionList();
var desc9 = new ActionDescriptor();
var idChnl = charIDToTypeID( "Chnl" );
var ref6 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idChnl = charIDToTypeID( "Chnl" );
var idRd = charIDToTypeID( "Rd " );
ref6.putEnumerated( idChnl, idChnl, idRd );
desc9.putReference( idChnl, ref6 );
var idGmm = charIDToTypeID( "Gmm " );
desc9.putDouble( idGmm, redGamma );
var idLvlA = charIDToTypeID( "LvlA" );
list1.putObject( idLvlA, desc9 );
var desc10 = new ActionDescriptor();
var idChnl = charIDToTypeID( "Chnl" );
var ref7 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idChnl = charIDToTypeID( "Chnl" );
var idGrn = charIDToTypeID( "Grn " );
ref7.putEnumerated( idChnl, idChnl, idGrn );
desc10.putReference( idChnl, ref7 );
var idGmm = charIDToTypeID( "Gmm " );
desc10.putDouble( idGmm, greenGamma );
var idLvlA = charIDToTypeID( "LvlA" );
list1.putObject( idLvlA, desc10 );
var desc11 = new ActionDescriptor();
var idChnl = charIDToTypeID( "Chnl" );
var ref8 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idChnl = charIDToTypeID( "Chnl" );
var idBl = charIDToTypeID( "Bl " );
ref8.putEnumerated( idChnl, idChnl, idBl );
desc11.putReference( idChnl, ref8 );
var idGmm = charIDToTypeID( "Gmm " );
desc11.putDouble( idGmm, blueGamma );
var idLvlA = charIDToTypeID( "LvlA" );
list1.putObject( idLvlA, desc11 );
desc8.putList( idAdjs, list1 );
var idLvls = charIDToTypeID( "Lvls" );
desc7.putObject( idT, idLvls, desc8 );
var desc = executeAction( idsetd, desc7, DialogModes.NO);
It doesn't match the results of doing this in the GUI but it's very close. At least on the 4 test image I used. I suppose that is due to rounding errors or the fact that I choose to use the middle value of the 3 channels as the target value and Adobe uses a different method.
Code: Select allvar doc = activeDocument;
doc.flatten();
var mainLayer = doc.activeLayer;
var filterLayer = mainLayer.duplicate ();
doc.activeLayer = filterLayer;
filterLayer.applyAverage();
var re = RegExp( '[123456789]+' );
var rValue = re.exec( doc.channels[0].histogram.toString() ).index/2;
var gValue = re.exec( doc.channels[1].histogram.toString() ).index/2;
var bValue = re.exec( doc.channels[2].histogram.toString() ).index/2;
var values = [ rValue, gValue, bValue ];
values = values.sort( function( a, b ){ return a < b } );
var targetValue = values[1];
var redGamma = Math.log( ( 255 / rValue ) ) / Math.log( ( 255 / targetValue ) );
var greenGamma = Math.log( ( 255 / gValue ) ) / Math.log( ( 255 / targetValue ) );
var blueGamma = Math.log( ( 255 / bValue ) ) / Math.log( ( 255 / targetValue ) );
// make the levels adjustment layer
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putClass( stringIDToTypeID( "adjustmentLayer" ) );
desc.putReference( stringIDToTypeID( "null" ), ref );
var typeDesc = new ActionDescriptor();
typeDesc.putClass( stringIDToTypeID( "type" ), stringIDToTypeID( "levels" ) );
desc.putObject( stringIDToTypeID( "using" ), stringIDToTypeID( "adjustmentLayer" ), typeDesc );
executeAction( stringIDToTypeID( "make" ), desc, DialogModes.NO );
//
var idsetd = charIDToTypeID( "setd" );
var desc7 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref5 = new ActionReference();
var idAdjL = charIDToTypeID( "AdjL" );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref5.putEnumerated( idAdjL, idOrdn, idTrgt );
desc7.putReference( idnull, ref5 );
var idT = charIDToTypeID( "T " );
var desc8 = new ActionDescriptor();
var idpresetKind = stringIDToTypeID( "presetKind" );
var idpresetKindType = stringIDToTypeID( "presetKindType" );
var idpresetKindCustom = stringIDToTypeID( "presetKindCustom" );
desc8.putEnumerated( idpresetKind, idpresetKindType, idpresetKindCustom );
var idAdjs = charIDToTypeID( "Adjs" );
var list1 = new ActionList();
var desc9 = new ActionDescriptor();
var idChnl = charIDToTypeID( "Chnl" );
var ref6 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idChnl = charIDToTypeID( "Chnl" );
var idRd = charIDToTypeID( "Rd " );
ref6.putEnumerated( idChnl, idChnl, idRd );
desc9.putReference( idChnl, ref6 );
var idGmm = charIDToTypeID( "Gmm " );
desc9.putDouble( idGmm, redGamma );
var idLvlA = charIDToTypeID( "LvlA" );
list1.putObject( idLvlA, desc9 );
var desc10 = new ActionDescriptor();
var idChnl = charIDToTypeID( "Chnl" );
var ref7 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idChnl = charIDToTypeID( "Chnl" );
var idGrn = charIDToTypeID( "Grn " );
ref7.putEnumerated( idChnl, idChnl, idGrn );
desc10.putReference( idChnl, ref7 );
var idGmm = charIDToTypeID( "Gmm " );
desc10.putDouble( idGmm, greenGamma );
var idLvlA = charIDToTypeID( "LvlA" );
list1.putObject( idLvlA, desc10 );
var desc11 = new ActionDescriptor();
var idChnl = charIDToTypeID( "Chnl" );
var ref8 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idChnl = charIDToTypeID( "Chnl" );
var idBl = charIDToTypeID( "Bl " );
ref8.putEnumerated( idChnl, idChnl, idBl );
desc11.putReference( idChnl, ref8 );
var idGmm = charIDToTypeID( "Gmm " );
desc11.putDouble( idGmm, blueGamma );
var idLvlA = charIDToTypeID( "LvlA" );
list1.putObject( idLvlA, desc11 );
desc8.putList( idAdjs, list1 );
var idLvls = charIDToTypeID( "Lvls" );
desc7.putObject( idT, idLvls, desc8 );
var desc = executeAction( idsetd, desc7, DialogModes.NO);
It doesn't match the results of doing this in the GUI but it's very close. At least on the 4 test image I used. I suppose that is due to rounding errors or the fact that I choose to use the middle value of the 3 channels as the target value and Adobe uses a different method.
Re: Set gray point - curves
I find this script fantastic
I wish that instead of the level tonal values
a curve level was created
someone can do it.
I wish that instead of the level tonal values
a curve level was created
someone can do it.