Skip to main content
Participating Frequently
October 11, 2013
Answered

Modifying Levels Adjustment Layer?

  • October 11, 2013
  • 4 replies
  • 11034 views

I'm using PS CS6 x64 for Win7. I'm trying to figure out how to change the values on a "levels" adjustment layer using javascript. I can't find any info anywhere. Oddly, the scripting listener doesn't seem to pick up modifications to the adjustment layer.

Anybody have any luck with this?

(Edit: more info)

This topic has been closed for replies.
Correct answer DBarranca

Another route could be this function that lets you specify inputWhite, inputBlack, gamma, outputWhite, outputBlack

setLevelAdj = function(inBlack, inWhite, gamma, outBlack, outWhite) {

  var d, d1, d2, l, l1, l2, r, r1, s2t;

  if (outBlack == null) {

    outBlack = 0;

  }

  if (outWhite == null) {

    outWhite = 255;

  }

  s2t = function(s) {

    return app.stringIDToTypeID(s);

  };

  d = new ActionDescriptor();

  r = new ActionReference();

  r.putEnumerated(s2t('adjustmentLayer'), s2t('ordinal'), s2t('targetEnum'));

  d.putReference(s2t('target'), r);

  d1 = new ActionDescriptor();

  d1.putEnumerated(s2t('presetKind'), s2t('presetKindType'), s2t('presetKindCustom'));

  l = new ActionList();

  d2 = new ActionDescriptor();

  r1 = new ActionReference();

  r1.putEnumerated(s2t('channel'), s2t('channel'), s2t('composite'));

  d2.putReference(s2t('channel'), r1);

  l1 = new ActionList();

  l1.putInteger(inBlack);

  l1.putInteger(inWhite);

  d2.putList(s2t('input'), l1);

  d2.putDouble(s2t('gamma'), gamma);

  l2 = new ActionList();

  l2.putInteger(outBlack);

  l2.putInteger(outWhite);

  d2.putList(s2t('output'), l2);

  l.putObject(s2t('levelsAdjustment'), d2);

  d1.putList(s2t('adjustment'), l);

  d.putObject(s2t('to'), s2t('levels'), d1);

  return executeAction(s2t('set'), d, DialogModes.NO);

};

Davide

4 replies

Kukurykus
Legend
March 11, 2018

That's probably bug. To force ScriptListener to record changes made to Adjustment Layer you have for example to choose / create other layer. When you then open SL log you will find 2 new records while the 1st refers changes to Adjustment Layer.

photogyulai
Inspiring
September 9, 2015

I guess i was lucky and after several try the script listener did pick up the settings of the levels adjustment layer setting.

I saw some code up here, but it didnt worked for me (maybe cos different version?! i dont know)


So here is the result >>

(i put some comment where the adjustable variables are)

var idsetd = charIDToTypeID( "setd" );

    var desc5 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref2 = new ActionReference();

        var idAdjL = charIDToTypeID( "AdjL" );

        var idOrdn = charIDToTypeID( "Ordn" );

        var idTrgt = charIDToTypeID( "Trgt" );

        ref2.putEnumerated( idAdjL, idOrdn, idTrgt );

    desc5.putReference( idnull, ref2 );

    var idT = charIDToTypeID( "T   " );

        var desc6 = new ActionDescriptor();

        var idpresetKind = stringIDToTypeID( "presetKind" );

        var idpresetKindType = stringIDToTypeID( "presetKindType" );

        var idpresetKindCustom = stringIDToTypeID( "presetKindCustom" );

        desc6.putEnumerated( idpresetKind, idpresetKindType, idpresetKindCustom );

        var idAdjs = charIDToTypeID( "Adjs" );

            var list1 = new ActionList();

                var desc7 = new ActionDescriptor();

                var idChnl = charIDToTypeID( "Chnl" );

                    var ref3 = new ActionReference();

                    var idChnl = charIDToTypeID( "Chnl" );

                    var idChnl = charIDToTypeID( "Chnl" );

                    var idCmps = charIDToTypeID( "Cmps" );

                    ref3.putEnumerated( idChnl, idChnl, idCmps );

                desc7.putReference( idChnl, ref3 );

                var idInpt = charIDToTypeID( "Inpt" );

                    var list2 = new ActionList();

                    list2.putInteger( 0 );     // Black point

                    list2.putInteger( 240 );  // White point

                desc7.putList( idInpt, list2 );

                var idGmm = charIDToTypeID( "Gmm " );

                desc7.putDouble( idGmm, 1.30 );  //Gamma point

            var idLvlA = charIDToTypeID( "LvlA" );

            list1.putObject( idLvlA, desc7 );

        desc6.putList( idAdjs, list1 );

    var idLvls = charIDToTypeID( "Lvls" );

    desc5.putObject( idT, idLvls, desc6 );

executeAction( idsetd, desc5, DialogModes.NO );

DBarranca
Legend
October 11, 2013

As a side note to the other answers, it's true that ScriptingListener sometimes misses to record the ActionManager code relative to changes into an Adjustment Layer.

Sometimes not.

Sometimes you've to make active a different layer in order for SL to output something. Sometimes you reboot and it works the first go.

(At least that's what I remember from when I had to deal with such things)

Davide

www.davidebarranca.com

jakebendAuthor
Participating Frequently
October 11, 2013

Davide,

That's interesting information. I'll try rebooting.

DBarranca
DBarrancaCorrect answer
Legend
October 11, 2013

Another route could be this function that lets you specify inputWhite, inputBlack, gamma, outputWhite, outputBlack

setLevelAdj = function(inBlack, inWhite, gamma, outBlack, outWhite) {

  var d, d1, d2, l, l1, l2, r, r1, s2t;

  if (outBlack == null) {

    outBlack = 0;

  }

  if (outWhite == null) {

    outWhite = 255;

  }

  s2t = function(s) {

    return app.stringIDToTypeID(s);

  };

  d = new ActionDescriptor();

  r = new ActionReference();

  r.putEnumerated(s2t('adjustmentLayer'), s2t('ordinal'), s2t('targetEnum'));

  d.putReference(s2t('target'), r);

  d1 = new ActionDescriptor();

  d1.putEnumerated(s2t('presetKind'), s2t('presetKindType'), s2t('presetKindCustom'));

  l = new ActionList();

  d2 = new ActionDescriptor();

  r1 = new ActionReference();

  r1.putEnumerated(s2t('channel'), s2t('channel'), s2t('composite'));

  d2.putReference(s2t('channel'), r1);

  l1 = new ActionList();

  l1.putInteger(inBlack);

  l1.putInteger(inWhite);

  d2.putList(s2t('input'), l1);

  d2.putDouble(s2t('gamma'), gamma);

  l2 = new ActionList();

  l2.putInteger(outBlack);

  l2.putInteger(outWhite);

  d2.putList(s2t('output'), l2);

  l.putObject(s2t('levelsAdjustment'), d2);

  d1.putList(s2t('adjustment'), l);

  d.putObject(s2t('to'), s2t('levels'), d1);

  return executeAction(s2t('set'), d, DialogModes.NO);

};

Davide

c.pfaffenbichler
Community Expert
Community Expert
October 11, 2013

Why, what are you trying to achieve exactly?

 

Edit: To get an idea about the complexity of evaluating the values in an existing Adjustment Layer (Curves in this case, though) check out: curveAdjustmentToACV

jakebendAuthor
Participating Frequently
October 11, 2013

I need to make a non-destructive level adjustment to multiple layers in a specific layerset. The reason for scripting it is because it's part of a toolset for performing specific (repetative) mathematical adjustments to images. It's all part of a toolset I'm developing for physically conservative rendering techniques.

The hacky workaround I'm using is to use Applescript to invoke a PS action that makes the adjustment I need, but I hate this solution.

I could theoretically use curves instead of levels, but part of the adjustment is going from gamma to linear space (but still working in sRGB). That would mean I'd either need to set up a more complicated curve, or add an additional "exposure" adjustment layer. That's why I'm hoping to keep the levels adjustment layer.

I haven't quite digested the information in that curves example. I'll look into it.

JJMack
Community Expert
Community Expert
March 11, 2018

It's something I couldn't figure out long time with Adjustement Layer what I find now Michael L Hale did with no problem. I wonder what he used in his research to find stringIDToTypeID('legacyContentData')​ in that time? Who​ may give me answer?


I find it hard to find out many things about many thing when I come to Adobe Scripting.  Adobe does make Changes to Photoshop Script. Adobe added bugs of fail to add support for new features like new interpolation methods setting the brake existing Scripts.  And I see users in here use new features.  You seem to need to manually compare  Adobe JavaScript references manual to see what has been added.  Compare CC 2014 with CC 2015 JavaScript reference for example Application methods

I also saw some code the Tom Ruark posted using doProcess in this forum. So I tried it in CC 2018 and there seem to be a problem in doProcess in CC 2018 that may be new  I no longer have CC 2015, CC 2015.5 and CC 2017 installed.

Here is Tom's code with a little extra code thrown in.

/* The basic part of this script was posted by Tom Ruark to show how hard it is to catch ESC he wrote

"Depending on your operation it is difficult to capture the ESC key however. Your mileage may vary"

I had to try many many times to see ESC triger DoIt function's Catch Alert messages.

However doProgressSubTask did return the DoIt function failed when ESC was used and doProgressSubTask

caught ESC. So where User use the ESC key gets cough can vary and what is done can vary. For when the

DoIt function did catch the user cancelled it message that fact but took no action to return that fact

so the script keep on adding layers after I dismissed the DoIT message user cancelled.

As Tom wrote your mileage may vary so keep hitting the ESC the script may be able to be stopped else where

where ESC will not be ignored or just noted.

Note: doProcess, doForceProcess and doProgressSubTask seems to have been add to Photoshop Scripting in CC 2015

DoProcess does not seem to work correctly in CC 2018 if the script is run when there is no open document

in CC 2018. A new document will be opened and layers will be added. However, no progress bar will be displayed.

DoForcedProcess Does display a progress bar. I no longer have cc 2015, cc 2015.5 or CC 2017 installed to test

with they have many bugs perhaps Adobe will fix CC 2018.

*/

var d;

//if (CheckVersion(16)) doForcedProgress("Testing", "Testing()");

if (CheckVersion(16)) doProgress("Testing", "Testing()"); // this waits 3 or so seconds before showing

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

function Testing() {

    try {

        if (documents.length == 0)

            d = documents.add();

        else

            d = activeDocument;

        var keepGoing = true;

        for (var i = 0; i < 100 && keepGoing; i++) {

            keepGoing = doProgressSubTask(i, 100, "DoIt()");

         }

        if (!keepGoing)

            alert("User canceled keepGoing=" + keepGoing);

    } catch(e) {

        alert("Testing: " + e);

    }

}

function DoIt() {

    try {

        d.artLayers.add();

    }

    catch(e) {

        alert("DoIt: " + e);

    }

}

// CheckVersion

function CheckVersion(PSV) {

var numberArray = version.split(".");

if ( numberArray[0] < PSV ) {

alert( "You must use Photoshop " + PSV + " or later to run this script!" );

return false;

}

else return true;

}

JJMack