Skip to main content
Known Participant
April 30, 2020
Answered

Smart Exposure Compensation Script

  • April 30, 2020
  • 4 replies
  • 2143 views

Hello,

How can I achieve following action:

 - I have a bulk of 1000 images (CGI scanned textures)

 - I would like to have an action that:

       loads image, blurres it by 1000px (or average filter blur), measures average color, reverse back to non-blurred image and applies Camera Raw exposure by following rules:

       if average color is around 128RGB, nothing changes, if average color is around 64RGB - it applies +0,2E camera raw exposure, if average color is around 192RGB - it applies -0,2E camera raw exposure. I shall be able to make any number of these rules/points - or it would be better if I could import a curve defining this behaviour.

       This shall become an action - so I can apply it with Image Processor and choose what format to save.

 

Thank you for your help!
Jakub

This topic has been closed for replies.
Correct answer Stephen Marsh

Thanks to SuperMerlin, I have adapted code that added label metadata based on mean histogram values. This script will open a folder of files and save them in the same format as the original files, overwriting the originals (so work on copies until you have fully tested and are happy). You shouldn't need to apply the average filter.

 

 

// Special thanks to SuperMerlin for the original script
//forums.adobe.com/message/9700071#9700071

// Modified by Stephen Marsh, 2020
//community.adobe.com/t5/photoshop/smart-exposure-compensation-script/m-p/11093731

#target photoshop;
app.bringToFront();

main();

function main() {
    var inputFolder = Folder.selectDialog("Please select folder to process");
    if (inputFolder === null) return;
    var fileList = inputFolder.getFiles();
    for (var a in fileList) {
        open(fileList[a]);
        var EXT = fileList[a].name.toLowerCase().match(/[^\.]+$/).toString();
        var mean = meanHist(activeDocument.histogram).toFixed(0);
        if ((EXT)) {
            switch (true) {
                case (mean <= 110): // Mean histogram less than or equal to 110
                    crExposurePointTwo(fileList[a]);
                    break;
                case (mean >= 111 && mean <= 180): // Mean histogram between 111 and 180
                    (fileList[a]);
                    break;
                case (mean >= 181): // Mean histogram greater than or equal to 181
                    crExposureNegPointTwo(fileList[a]);
                    break;
                default:
                    break;
            }
        }
        app.activeDocument.close(SaveOptions.SAVECHANGES);
    }
}

function meanHist(hist) {
    var acc = 0;
    var cnt = 0;
    for (var i = 0; i < hist.length; i++) {
        acc += i * hist[i];
        cnt += hist[i];
    }
    return acc / cnt;
}

function crExposurePointTwo() {
    //community.adobe.com/t5/photoshop/is-there-any-jsx-to-execute-the-auto-tone-of-camera-raw/m-p/10167490
    var desc1 = new ActionDescriptor();
    desc1.putDouble(charIDToTypeID('Ex12'), 0.200000); // var expValue
    executeAction(stringIDToTypeID('Adobe Camera Raw Filter'), desc1, DialogModes.NO);
}

function crExposureNegPointTwo() {
    //community.adobe.com/t5/photoshop/is-there-any-jsx-to-execute-the-auto-tone-of-camera-raw/m-p/10167490
    var desc1 = new ActionDescriptor();
    desc1.putDouble(charIDToTypeID('Ex12'), -0.200000); // var expValue
    executeAction(stringIDToTypeID('Adobe Camera Raw Filter'), desc1, DialogModes.NO);
}

 

 

https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html

4 replies

Stephen Marsh
Community Expert
Stephen MarshCommunity ExpertCorrect answer
Community Expert
May 1, 2020

Thanks to SuperMerlin, I have adapted code that added label metadata based on mean histogram values. This script will open a folder of files and save them in the same format as the original files, overwriting the originals (so work on copies until you have fully tested and are happy). You shouldn't need to apply the average filter.

 

 

// Special thanks to SuperMerlin for the original script
//forums.adobe.com/message/9700071#9700071

// Modified by Stephen Marsh, 2020
//community.adobe.com/t5/photoshop/smart-exposure-compensation-script/m-p/11093731

#target photoshop;
app.bringToFront();

main();

function main() {
    var inputFolder = Folder.selectDialog("Please select folder to process");
    if (inputFolder === null) return;
    var fileList = inputFolder.getFiles();
    for (var a in fileList) {
        open(fileList[a]);
        var EXT = fileList[a].name.toLowerCase().match(/[^\.]+$/).toString();
        var mean = meanHist(activeDocument.histogram).toFixed(0);
        if ((EXT)) {
            switch (true) {
                case (mean <= 110): // Mean histogram less than or equal to 110
                    crExposurePointTwo(fileList[a]);
                    break;
                case (mean >= 111 && mean <= 180): // Mean histogram between 111 and 180
                    (fileList[a]);
                    break;
                case (mean >= 181): // Mean histogram greater than or equal to 181
                    crExposureNegPointTwo(fileList[a]);
                    break;
                default:
                    break;
            }
        }
        app.activeDocument.close(SaveOptions.SAVECHANGES);
    }
}

function meanHist(hist) {
    var acc = 0;
    var cnt = 0;
    for (var i = 0; i < hist.length; i++) {
        acc += i * hist[i];
        cnt += hist[i];
    }
    return acc / cnt;
}

function crExposurePointTwo() {
    //community.adobe.com/t5/photoshop/is-there-any-jsx-to-execute-the-auto-tone-of-camera-raw/m-p/10167490
    var desc1 = new ActionDescriptor();
    desc1.putDouble(charIDToTypeID('Ex12'), 0.200000); // var expValue
    executeAction(stringIDToTypeID('Adobe Camera Raw Filter'), desc1, DialogModes.NO);
}

function crExposureNegPointTwo() {
    //community.adobe.com/t5/photoshop/is-there-any-jsx-to-execute-the-auto-tone-of-camera-raw/m-p/10167490
    var desc1 = new ActionDescriptor();
    desc1.putDouble(charIDToTypeID('Ex12'), -0.200000); // var expValue
    executeAction(stringIDToTypeID('Adobe Camera Raw Filter'), desc1, DialogModes.NO);
}

 

 

https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html

JakubCechAuthor
Known Participant
May 1, 2020

Stephen! You are a true wizard!
This works like a charm and its super fast! Wow!
I honestly am so thankful - also ultra fast to run, no words! :))
Before me tagging this as the correct answer (which it really is based on my post), I woul love to ask if we could potentially take this little further.
Now by running this I realised one thing - to make this smooth I would need to make 50 - 100 points = 50 - 100 ifs.
That would be doable - but what if I need to change or experiment with numbers? I would need to change all values multiple times and that would take forever... Therefor I would love to ask - would it be possible to make the "if" part based on a curve? Please see attached.
All this would require is probably a path to saved "ACV" curve and two exposure compensation values - minimum and maximum.

This would be an incredible help. I am sorry for realizing this later.
Jakub

PS: Would the script possibly not overwrite files? Just add "_2" or anything. I already see myself loosing some part of library.

Stephen Marsh
Community Expert
Community Expert
May 1, 2020

Thanks for the kind words, I just hack away – sometimes with success, I couldn't have written the script that SuperMerlin created.

 

I'll have to pass the baton over to somebody else. I have tried to make the requested modifications (both saving with a new filename and using a curve preset), however, I keep breaking the script.

 

Some snippets for the .acv code:

 

 

 

 

lightenCurvePreset();

function lightenCurvePreset() {
    var idCrvs = charIDToTypeID("Crvs");
    var desc29 = new ActionDescriptor();
    var idpresetKind = stringIDToTypeID("presetKind");
    var idpresetKindType = stringIDToTypeID("presetKindType");
    var idpresetKindUserDefined = stringIDToTypeID("presetKindUserDefined");
    desc29.putEnumerated(idpresetKind, idpresetKindType, idpresetKindUserDefined);
    var idUsng = charIDToTypeID("Usng");
    desc29.putPath(idUsng, new File("~/Desktop/Lighten.acv")); // Path to curve preset
    executeAction(idCrvs, desc29, DialogModes.NO);
}


darkenCurvePreset();

function darkenCurvePreset() {
    var idCrvs = charIDToTypeID("Crvs");
    var desc10 = new ActionDescriptor();
    var idpresetKind = stringIDToTypeID("presetKind");
    var idpresetKindType = stringIDToTypeID("presetKindType");
    var idpresetKindUserDefined = stringIDToTypeID("presetKindUserDefined");
    desc10.putEnumerated(idpresetKind, idpresetKindType, idpresetKindUserDefined);
    var idUsng = charIDToTypeID("Usng");
    desc10.putPath(idUsng, new File("~/Desktop/Darken.acv")); // Path to curve preset
    executeAction(idCrvs, desc10, DialogModes.NO);
}

 

 

 

 

Stephen Marsh
Community Expert
Community Expert
April 30, 2020

Code snippets to get you started (not full working code):

 

 

app.activeDocument.activeLayer.applyAverage();

 

 

And:

 

 

// Call The Camera Raw Filter Exposure Function with a value of +0.2
crExposure(expValue = 0.200000);

// Call The Camera Raw Filter Exposure Function with a value of -0.2
crExposure(expValue = -0.200000);

function crExposure() {
    //community.adobe.com/t5/photoshop/is-there-any-jsx-to-execute-the-auto-tone-of-camera-raw/m-p/10167490
    var desc1 = new ActionDescriptor();
    desc1.putDouble(charIDToTypeID('Ex12'), expValue); // var expValue
    executeAction(stringIDToTypeID('Adobe Camera Raw Filter'), desc1, DialogModes.NO);
}

 

 

Stephen Marsh
Community Expert
Community Expert
April 30, 2020

Saves into which format?

JakubCechAuthor
Known Participant
April 30, 2020

This shall become an action - so I can apply it with Image Processor and choose what format to save.
If this is not available, I would go with 16bit tiff with no compression.

Stephen Marsh
Community Expert
Community Expert
April 30, 2020

Sorry, misread that!

c.pfaffenbichler
Community Expert
Community Expert
April 30, 2020

Why blur by 1000px and not use the Average Filter right away? 

JakubCechAuthor
Known Participant
April 30, 2020

I do not know that tool - if it does the same, no problem!

c.pfaffenbichler
Community Expert
Community Expert
April 30, 2020

Filter > Blur > Average