• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Using color sampler values with curves adjustment layer

Explorer ,
Oct 29, 2012 Oct 29, 2012

Copy link to clipboard

Copied

Hi, I have just started trying to teach myself javascript.  Based on preliminary research, it's become apparent that there are many functions in Photoshop that are either extremely cumbersome or impossible to code by hand without using the Script Listener.

My  goal is as follows: first, I will manually load two photos as layers in a single document.  Then I will manually place two or more color sampler points on the document.  At this point I would like the script to create a curves adjustment layer (ideally clipped to layer 2) and place as individual channel anchor points  the RGB data from the color sampler points on Layer 2, and then adjust the output of the points on each channel to the color sampler RGB values of layer 1.  

As my first script, I realize this is probably going to be a lot of work.

I did find some code that returns the average value of manually placed color sampler points.  Conceptually then, I would need to add code which creates a new curves adjustment layer and adds those RGB values (from a specific layer)  as anchor points on the individual channels,  and then hides one layer and looks at the RGB values of the color sampler points, and uses them as the output values for each anchor point.

Sounds simple enough from a conceptual standpoint.

I'm looking for some guidance on how to get started.

Which parts will I definitely need Scriptlistener for and will that be adequate to do the job?

How would you recommend I get started on this?

Thanks very much for any input.

TOPICS
Actions and scripting

Views

4.3K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe
Community Expert ,
Nov 01, 2012 Nov 01, 2012

Copy link to clipboard

Copied

it's become apparent that there are many functions in Photoshop that are either extremely cumbersome or impossible to code by hand without using the Script Listener.

Actually you may not need to use ScriptingListener.plugin yourself if you can find the code elsewhere but the

Document Object Model

will indeed not suffice for the task at hand (as far as I can tell) and you will have to use

Action Manager code.

DOM code may look neater and be more easy to read but it has drawbacks – that not all functions can be controlled thus being the probably most significant one.

I guess you need to record the creation of a Curves Layer with the appropriate number of points for the appropriate number of Channels and feed the numbers you collect from the ColorSamplers for the two Layers into that.

As you are vague about the actual number of ColorSamplers the task becomes more complicated and you may have to utilize a for-clause and a function for creating the points.

In my opinion this task is a problematic choice for a »first script«.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Nov 01, 2012 Nov 01, 2012

Copy link to clipboard

Copied

You should be able to get an average color from the colorSampler itself without any additional code as long as the area you want to average is one of the sizes in the sampler tool options. If the layers overlap you will need to hide/show the top layer to get the color from both layers as colorSampler reads the composite image.

Because you are doing most of the steps manually I don't think it would be too hard to script. I think an outline of the script would look something like this.

1. hide the top layer - DOM

2. read the color from the samplers and store the solidColor objects - DOM

3. show the top layer - DOM

4. read the colors again and store those - DOM

5. create a curve adjustment layer - Action Manager(scriptlistener)

6. move the adjustment layer to the top(if needed) and create clipping group - DOM

7. edit the adjustment layer using the stored color values - Action Manager

The hard part will be step 7. Especially if you want to have a flexible number of colorSampler/curve points. But with a little effort and maybe some help from this forum I think you can come up with a script that does what you want.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Nov 01, 2012 Nov 01, 2012

Copy link to clipboard

Copied

Thank you both for your thoughts.  I see Action Manager = ScriptListener, which is good to know.  I will be working almost always with two color sampler points, so based on what you've both indicated, that could simplify things.  Is the Adobe Scripting Guide the best place to go to find the necessary commands to do steps 1-4, and 6?

In step 7, if I use the action Manager, how do I indicate I want to recall the stored color sampler values?  I could be (and am probably) way off here, but I thought Action manager records scripting code based on what happens on the screen, so if the color sampler points are stored as variables in the script, it seems like I wouldn't be able to access them in the Photoshop interface to record with Action Manager. I.E. Action Manager would record the numerical value of the points that I move in the curves without tying them to the color sampler variables.

Conceptually it seems like it should be easy to write code that sets the color sampler points as variables, then calls the channels of the curves layer and sets the input and output numbers to the desired variables. 

Thanks again for giving me some guidance.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Nov 02, 2012 Nov 02, 2012

Copy link to clipboard

Copied

I think that I was somewhat miss-leading. The scriptlistener plug-in outputs Action Manger code but that is not the same as it being equal. Yes, scirptlistener only records the settings used for that recorded acton. Sometimes you can use the code straight from the scriptlistener log but most of the time you will want to edit it so it uses variables instead of the hard coded settings.

I have been thinking about how this script would work. For one thing it would be limited to 4 points on the curve because of the ColorSampler limit of four samples. The ActionDescriptor for a curve expects the points to be in order so you would either need to place the colorSamplers in order i.e. the first sampler is for the black point of the curve or come up with a way to determine what sample is to be used for each curve point. Creating the curve descriptor will be the hardest part of writing a script to do this task.

As for the rest, yes, it is easy. I would do something like this...

// create a function fo hold most of the code

function createCurveAdjustmetFromColorSamplers(){

    // first add some condition checks

    // needs an open document in a color mode that supports layers

    if(app.documents.length == 0 || ( app.activeDocument.mode == DocumentMode.BITMAP || app.activeDocument.mode == DocumentMode.INDEXEDCOLOR ) ){   

        alert('This script requires a document in Greyscale, RGB, CMYK, or Lab mode.');

        return;

    }

    // check for at least two colorSamplers

    if(app.activeDocument.colorSamplers.length < 2 ){

        alert('This script requires at least two colorSamplers.');

        return;

    }

    // last check for at least two layers - assume they will be on same level( not in layerSet )

    if(app.activeDocument.layers.length < 2 ){

        alert('This script requires at least two layers.');

        return;

    }

    // create varaibles to hold the colorSampler's color property for each layer

    // for the bottom layer

    var outputArray = new Array();

    // for top layer - array could also be created this way

    var inputArray = [];

    // store the number of samples because it will be needed in more than one place

    var numberOfSamples = app.activeDocument.colorSamplers.length;

   

    // hide the top layer

    app.activeDocument.layers[0].visible = false;

    // collect the samples from the bottom layer

    for(var sampleIndex = 0; sampleIndex < numberOfSamples; sampleIndex++ ){

        outputArray.push(app.activeDocument.colorSamplers[sampleIndex].color);

    }

    // turn the top layer back on

    app.activeDocument.layers[0].visible = true;

    // collect those samples

    for(var sampleIndex = 0; sampleIndex < numberOfSamples; sampleIndex++ ){

        inputArray.push(app.activeDocument.colorSamplers[sampleIndex].color);

    }

    // make sure the top layer is the activeLayer

    app.activeDocument.activeLayer = app.activeDocument.layers[0];

    // use Action Manager code to create new curve adjustment layer

    makeCurveAdjustmentLayer();

}

function makeCurveAdjustmentLayer(){//works with any mode

   var desc = new ActionDescriptor();

   var ref = new ActionReference();

     ref.putClass( charIDToTypeID( "AdjL" ) );

   desc.putReference( charIDToTypeID( "null" ), ref );

   var desc1 = new ActionDescriptor();

     desc1.putClass( charIDToTypeID( "Type" ), charIDToTypeID("Crvs" ) );

   desc.putObject( charIDToTypeID( "Usng" ), charIDToTypeID( "AdjL" ), desc1 );

   executeAction( charIDToTypeID( "Mk  " ), desc, DialogModes.NO );

}

// call the function to run the script

createCurveAdjustmetFromColorSamplers();

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Nov 02, 2012 Nov 02, 2012

Copy link to clipboard

Copied

Thank you Michael! That's very helpful.  I will look over the code and do some more research and come back when I have more specific questions. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 03, 2012 Nov 03, 2012

Copy link to clipboard

Copied

The following function can be used to create RGB Curves Layers with varying numbers of points.

The Arrays for the source- and target values for the RGB-Channels are just listed in an Array themselves, so the first and second (red), third and fourth (green), fifth and sixth (blue) arrays should have identical numbers of elements.

And like I pointed out in the last post the source numbers in one Array should be different, I guess.

#target photoshop

var theArray = [[0, 128, 255], [0, 150, 255], [0, 128, 255], [0, 90, 255], [0, 75, 230, 255], [0, 30, 180, 255]];

rgbCurvesLayer (theArray);

////// make rgb curves layer //////

function rgbCurvesLayer (theArray) {

// =======================================================

var idMk = charIDToTypeID( "Mk  " );

    var desc5 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref2 = new ActionReference();

        var idAdjL = charIDToTypeID( "AdjL" );

        ref2.putClass( idAdjL );

    desc5.putReference( idnull, ref2 );

    var idUsng = charIDToTypeID( "Usng" );

        var desc6 = new ActionDescriptor();

        var idType = charIDToTypeID( "Type" );

            var desc7 = new ActionDescriptor();

            var idpresetKind = stringIDToTypeID( "presetKind" );

            var idpresetKindType = stringIDToTypeID( "presetKindType" );

            var idpresetKindDefault = stringIDToTypeID( "presetKindDefault" );

            desc7.putEnumerated( idpresetKind, idpresetKindType, idpresetKindDefault );

        var idCrvs = charIDToTypeID( "Crvs" );

        desc6.putObject( idType, idCrvs, desc7 );

    var idAdjL = charIDToTypeID( "AdjL" );

    desc5.putObject( idUsng, idAdjL, desc6 );

executeAction( idMk, desc5, DialogModes.NO );

// =======================================================

var idsetd = charIDToTypeID( "setd" );

    var desc8 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref3 = new ActionReference();

        var idAdjL = charIDToTypeID( "AdjL" );

        var idOrdn = charIDToTypeID( "Ordn" );

        var idTrgt = charIDToTypeID( "Trgt" );

        ref3.putEnumerated( idAdjL, idOrdn, idTrgt );

    desc8.putReference( idnull, ref3 );

    var idT = charIDToTypeID( "T   " );

        var desc9 = new ActionDescriptor();

        var idpresetKind = stringIDToTypeID( "presetKind" );

        var idpresetKindType = stringIDToTypeID( "presetKindType" );

        var idpresetKindCustom = stringIDToTypeID( "presetKindCustom" );

        desc9.putEnumerated( idpresetKind, idpresetKindType, idpresetKindCustom );

        var idAdjs = charIDToTypeID( "Adjs" );

            var list1 = new ActionList();

                var desc10 = new ActionDescriptor();

                var idChnl = charIDToTypeID( "Chnl" );

                    var ref4 = new ActionReference();

                    var idChnl = charIDToTypeID( "Chnl" );

                    var idChnl = charIDToTypeID( "Chnl" );

                    var idRd = charIDToTypeID( "Rd  " );

                    ref4.putEnumerated( idChnl, idChnl, idRd );

                desc10.putReference( idChnl, ref4 );

                var idCrv = charIDToTypeID( "Crv " );

                    var list2 = new ActionList();

// add r points;

for (var m = 0; m < theArray[0].length; m++) {

          addCurvePoint (list2, theArray[0], theArray[1])

          };

                desc10.putList( idCrv, list2 );

            var idCrvA = charIDToTypeID( "CrvA" );

            list1.putObject( idCrvA, desc10 );

                var desc15 = new ActionDescriptor();

                var idChnl = charIDToTypeID( "Chnl" );

                    var ref5 = new ActionReference();

                    var idChnl = charIDToTypeID( "Chnl" );

                    var idChnl = charIDToTypeID( "Chnl" );

                    var idGrn = charIDToTypeID( "Grn " );

                    ref5.putEnumerated( idChnl, idChnl, idGrn );

                desc15.putReference( idChnl, ref5 );

                var idCrv = charIDToTypeID( "Crv " );

                    var list3 = new ActionList();

// add g points;

for (var m = 0; m < theArray[2].length; m++) {

          addCurvePoint (list3, theArray[2], theArray[3])

          };

                desc15.putList( idCrv, list3 );

            var idCrvA = charIDToTypeID( "CrvA" );

            list1.putObject( idCrvA, desc15 );

                var desc20 = new ActionDescriptor();

                var idChnl = charIDToTypeID( "Chnl" );

                    var ref6 = new ActionReference();

                    var idChnl = charIDToTypeID( "Chnl" );

                    var idChnl = charIDToTypeID( "Chnl" );

                    var idBl = charIDToTypeID( "Bl  " );

                    ref6.putEnumerated( idChnl, idChnl, idBl );

                desc20.putReference( idChnl, ref6 );

                var idCrv = charIDToTypeID( "Crv " );

                    var list4 = new ActionList();

// add b points;

for (var m = 0; m < theArray[4].length; m++) {

          addCurvePoint (list4, theArray[4], theArray[5])

          };

                desc20.putList( idCrv, list4 );

            var idCrvA = charIDToTypeID( "CrvA" );

            list1.putObject( idCrvA, desc20 );

        desc9.putList( idAdjs, list1 );

    var idCrvs = charIDToTypeID( "Crvs" );

    desc8.putObject( idT, idCrvs, desc9 );

executeAction( idsetd, desc8, DialogModes.NO );

//

return app.activeDocument.activeLayer;

////// add curve point //////

function addCurvePoint (theList, valueHor, valueVer) {

var desc11 = new ActionDescriptor();

var idHrzn = charIDToTypeID( "Hrzn" );

desc11.putDouble( idHrzn, valueHor );

var idVrtc = charIDToTypeID( "Vrtc" );

desc11.putDouble( idVrtc, valueVer );

var idPnt = charIDToTypeID( "Pnt " );

theList.putObject( idPnt, desc11 );

};

};

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 03, 2012 Nov 03, 2012

Copy link to clipboard

Copied

Another possible issue might be if two sampled points have identical source values but different target values.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 04, 2012 Nov 04, 2012

Copy link to clipboard

Copied

Creating the curve descriptor will be the hardest part of writing a script to do this task.

I think getting the color values in order and checking if 0 or 255 have been picked or if they should be added to the ColorSamplers’ values and making sure no identical input values appear for any channel may be the tougher part.

Jbean25, could you post a pair of images (with the ColorSamplers) to show what a likely combination of actual images may be?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Nov 04, 2012 Nov 04, 2012

Copy link to clipboard

Copied

I think getting the color values in order and checking if 0 or 255 have been picked or if they should be added to the ColorSamplers’ values and making sure no identical input values appear for any channel may be the tougher part.

I guess I was thinking of creating an edit curve adjustment that could be used to create any curve adjustment layer in any color mode. A general function that could be used by any scripts.

But yes, all of the points you listed need to be addressed as part of creating the arguments to what ever function is used.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 10, 2012 Nov 10, 2012

Copy link to clipboard

Copied

I guess I was thinking of creating an edit curve adjustment that could be used to create any curve adjustment layer in any color mode.

You are right (edit: a Curves Layer function for all elligible color modes seems demanding).

I just assumed RGB would be the natural choice – which of course it need not be.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Nov 05, 2012 Nov 05, 2012

Copy link to clipboard

Copied

Here are a couple photos.  The color sampler points did not show up in the photos when inserted, so I've marked them on the top photo.  The goal is ultimately to blend the sky of the darker photo in the brighter exposure.  And the best way to do this is actually to use the color sampler points from both layers and take the average of them, and set the average  as the output (not swap the values as I indicated in my initial post). I didn't think this extra step of figuring out the average would require much effort once I figured out how to do the heavy lifting, so please excuse me if that confused things. For the photos below,  I would load the photos as layers.  Then using the sampler point on the left, I would look at the RGB values of it and then hide that layer and look at the RGB sampler values of the same point on the photo below it.  Then I would take the average of the R value for the top and bottom and use as the output for the curve layers I create, one for each photo.  (the input is obtained by shift+clicking on the color sampler on each layer).  I would repeat the process for the right most color sampler point, so that each curve now has two anchor points on each RGB channel.

That sounds long winded, but I hope it makes sense. And again, I apologize for any inconvenience.

DSC_0036 dnsz to pst adobe forum J.jpg0037 dnsz to pst adobe forum j.jpg

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 10, 2012 Nov 10, 2012

Copy link to clipboard

Copied

The markings were unneccesary (and disruptive) as the Color Pickers were saved with the image.

Could you show what result you intend?

As the images seem to be RGB anyway, have you tried combining Michael’s code with the function I posted?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Nov 13, 2012 Nov 13, 2012

Copy link to clipboard

Copied

Hi c.pfaffenbichler,

I have had some computer issues the last few days and am just now able to work on this in earnest. 

First, I tried to run the  Michael's code in the script editor, but it returned an error. I believe this is because of the conditions set, which required layers to be active, etc.  I'm nost sure then, what use the script editor will be in this particular case.  Next I then ran it in CS5, and separately ran your code in CS5 as well. 

Michael's code created a new curves layer, and if I understand it correctly, set the groundwork for me to be able to add in curves points using the color sampler variables he created. 

Your code returned a curves layer with anchor points in the R,G,B channels, the input and output values are not entirely clear to me upon trying to parse the code.  The B channel for some reason was assigned two anchor points with output values. The net effect of the curves adjustment was to make the photo much more red in appearance.  I realize I need to learn a lot more code to really understand these scripts that have been writtenn

I'm reattaching the photos with a 3rd, which is the result of the adjustment.  I have removed the painted circles around the color sampler points.  The top most photo below is the adjusted photo, the second is the darker sky exposure and the lowest photo is a brighter exposure for the hills and river. The brightness of the sky in the  top photo is kind of mid-way between the brighter and darker photos.  The main thing is that it, and the background hills retains detail, which can be adjusted later in photoshop. DSC_0036 blnd jw tech_no adj_ dnsz850 adobe forum j.jpg0037 dnsz to pst adobe forum j.jpgDSC_0036 dnsz to pst adobe forum J_clr samplers.jpg

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Nov 13, 2012 Nov 13, 2012

Copy link to clipboard

Copied

I should note that masks were created to reveal the adjustment selectively.

Also, thank you very much for your help and the time you  have spent on this.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 25, 2012 Nov 25, 2012

Copy link to clipboard

Copied

The function I had provided was an example into which you would need to feed the values you got with Mike’s code.

The code below would create a Curves Layer as shown in the screenshot, but I’m not sure it would work reasonably for all cases.

curvesColorPickerScr.jpg

// with code by mike hale;

// 2012, use it at your own risk;

// call the function to run the script

#target photoshop

createCurveAdjustmetFromColorSamplers();

// create a function fo hold most of the code

function createCurveAdjustmetFromColorSamplers(){

    // first add some condition checks

    // needs an open document in a color mode that supports layers

    if(app.documents.length == 0 || ( app.activeDocument.mode == DocumentMode.BITMAP || app.activeDocument.mode == DocumentMode.INDEXEDCOLOR ) ){   

        alert('This script requires a document in Greyscale, RGB, CMYK, or Lab mode.');

        return;

    }

    // check for at least two colorSamplers

    if(app.activeDocument.colorSamplers.length < 2 ){

        alert('This script requires at least two colorSamplers.');

        return;

    }

    // last check for at least two layers - assume they will be on same level( not in layerSet )

    if(app.activeDocument.layers.length < 2 ){

        alert('This script requires at least two layers.');

        return;

    }

    // create varaibles to hold the colorSampler's color property for each layer

    // for the bottom layer

    var outputArray = new Array();

    // for top layer - array could also be created this way

    var inputArray = [];

    // store the number of samples because it will be needed in more than one place

    var numberOfSamples = app.activeDocument.colorSamplers.length;

    // hide the top layer

    app.activeDocument.layers[0].visible = false;

    // collect the samples from the bottom layer

    for(var sampleIndex = 0; sampleIndex < numberOfSamples; sampleIndex++ ){

        outputArray.push(app.activeDocument.colorSamplers[sampleIndex].color);

    }

    // turn the top layer back on

    app.activeDocument.layers[0].visible = true;

    // collect those samples

    for(var sampleIndex = 0; sampleIndex < numberOfSamples; sampleIndex++ ){

        inputArray.push(app.activeDocument.colorSamplers[sampleIndex].color);

    }

    // make sure the top layer is the activeLayer

    app.activeDocument.activeLayer = app.activeDocument.layers[0];

// create arrays of the color values:

var theArray = [[0, 0, 0, 0, 0, 0]];

for (var m = 0; m < inputArray.length; m++) {

theArray.push([inputArray.rgb.red, outputArray.rgb.red, inputArray.rgb.green, outputArray.rgb.green, inputArray.rgb.blue, outputArray.rgb.blue]);

};

theArray.push([255, 255, 255, 255, 255, 255]);

// sort;

theArray.sort(sortArrayByIndexedItem);

// makeCurveAdjustmentLayer();

rgbCurvesLayer (theArray)

};

////// make rgb curves layer //////

function rgbCurvesLayer (theArray) {

// =======================================================

var idMk = charIDToTypeID( "Mk  " );

    var desc5 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref2 = new ActionReference();

        var idAdjL = charIDToTypeID( "AdjL" );

        ref2.putClass( idAdjL );

    desc5.putReference( idnull, ref2 );

    var idUsng = charIDToTypeID( "Usng" );

        var desc6 = new ActionDescriptor();

        var idType = charIDToTypeID( "Type" );

            var desc7 = new ActionDescriptor();

            var idpresetKind = stringIDToTypeID( "presetKind" );

            var idpresetKindType = stringIDToTypeID( "presetKindType" );

            var idpresetKindDefault = stringIDToTypeID( "presetKindDefault" );

            desc7.putEnumerated( idpresetKind, idpresetKindType, idpresetKindDefault );

        var idCrvs = charIDToTypeID( "Crvs" );

        desc6.putObject( idType, idCrvs, desc7 );

    var idAdjL = charIDToTypeID( "AdjL" );

    desc5.putObject( idUsng, idAdjL, desc6 );

executeAction( idMk, desc5, DialogModes.NO );

// =======================================================

var idsetd = charIDToTypeID( "setd" );

    var desc8 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref3 = new ActionReference();

        var idAdjL = charIDToTypeID( "AdjL" );

        var idOrdn = charIDToTypeID( "Ordn" );

        var idTrgt = charIDToTypeID( "Trgt" );

        ref3.putEnumerated( idAdjL, idOrdn, idTrgt );

    desc8.putReference( idnull, ref3 );

    var idT = charIDToTypeID( "T   " );

        var desc9 = new ActionDescriptor();

        var idpresetKind = stringIDToTypeID( "presetKind" );

        var idpresetKindType = stringIDToTypeID( "presetKindType" );

        var idpresetKindCustom = stringIDToTypeID( "presetKindCustom" );

        desc9.putEnumerated( idpresetKind, idpresetKindType, idpresetKindCustom );

        var idAdjs = charIDToTypeID( "Adjs" );

            var list1 = new ActionList();

                var desc10 = new ActionDescriptor();

                var idChnl = charIDToTypeID( "Chnl" );

                    var ref4 = new ActionReference();

                    var idChnl = charIDToTypeID( "Chnl" );

                    var idChnl = charIDToTypeID( "Chnl" );

                    var idRd = charIDToTypeID( "Rd  " );

                    ref4.putEnumerated( idChnl, idChnl, idRd );

                desc10.putReference( idChnl, ref4 );

                var idCrv = charIDToTypeID( "Crv " );

                    var list2 = new ActionList();

// add r points;

for (var m = 0; m < theArray.length; m++) {

          addCurvePoint (list2, theArray, 0)

          };

                desc10.putList( idCrv, list2 );

            var idCrvA = charIDToTypeID( "CrvA" );

            list1.putObject( idCrvA, desc10 );

                var desc15 = new ActionDescriptor();

                var idChnl = charIDToTypeID( "Chnl" );

                    var ref5 = new ActionReference();

                    var idChnl = charIDToTypeID( "Chnl" );

                    var idChnl = charIDToTypeID( "Chnl" );

                    var idGrn = charIDToTypeID( "Grn " );

                    ref5.putEnumerated( idChnl, idChnl, idGrn );

                desc15.putReference( idChnl, ref5 );

                var idCrv = charIDToTypeID( "Crv " );

                    var list3 = new ActionList();

// add g points;

for (var m = 0; m < theArray.length; m++) {

          addCurvePoint (list3, theArray, 2)

          };

                desc15.putList( idCrv, list3 );

            var idCrvA = charIDToTypeID( "CrvA" );

            list1.putObject( idCrvA, desc15 );

                var desc20 = new ActionDescriptor();

                var idChnl = charIDToTypeID( "Chnl" );

                    var ref6 = new ActionReference();

                    var idChnl = charIDToTypeID( "Chnl" );

                    var idChnl = charIDToTypeID( "Chnl" );

                    var idBl = charIDToTypeID( "Bl  " );

                    ref6.putEnumerated( idChnl, idChnl, idBl );

                desc20.putReference( idChnl, ref6 );

                var idCrv = charIDToTypeID( "Crv " );

                    var list4 = new ActionList();

// add b points;

for (var m = 0; m < theArray.length; m++) {

          addCurvePoint (list4, theArray, 4)

          };

                desc20.putList( idCrv, list4 );

            var idCrvA = charIDToTypeID( "CrvA" );

            list1.putObject( idCrvA, desc20 );

        desc9.putList( idAdjs, list1 );

    var idCrvs = charIDToTypeID( "Crvs" );

    desc8.putObject( idT, idCrvs, desc9 );

executeAction( idsetd, desc8, DialogModes.NO );

//

return app.activeDocument.activeLayer;

////// add curve point //////

function addCurvePoint (theList, valueHor, theNumber) {

var desc11 = new ActionDescriptor();

var idHrzn = charIDToTypeID( "Hrzn" );

desc11.putDouble( idHrzn, valueHor[theNumber] );

var idVrtc = charIDToTypeID( "Vrtc" );

desc11.putDouble( idVrtc, valueHor[theNumber+1] );

var idPnt = charIDToTypeID( "Pnt " );

theList.putObject( idPnt, desc11 );

};

};

////// sort a double array, thanks to sam, http://www.rhinocerus.net/forum/lang-javascript/ //////

function sortArrayByIndexedItem(a,b) {

var theIndex = 0;

if (a[theIndex]<b[theIndex]) return -1;

if (a[theIndex]>b[theIndex]) return 1;

return 0;

};

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Mar 20, 2021 Mar 20, 2021

Copy link to clipboard

Copied

Hi! I am currently trying to achieve pretty much the same as @Jbean25  in Photoshop CC. I need to adjust the curve so that the RGB numbers of ColorSampler1 match the numbers of ColorSampler2. I have two layers and only two ColorSamplers set manually. But when I try to run the script from above created by @c.pfaffenbichler  I get error messages like:

Error 8800: General Photoshop error occurred. This functionality may not be available in this version of Photoshop.

 

I tried it on an older PC with CS6 and got the same result, so it doesn`t seem to be about the software version. 

What am I doing wrong? I`ll attach a small .psd file of what I am trying to achieve.


Thank you!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 20, 2021 Mar 20, 2021

Copy link to clipboard

Copied

That’s not what the Script is intended to do; the Script is intended to adjust the Curves Layer based on the Colorpicker values at the same position on two Layers, not adjust the values of one Colorpicker according to another Colorpicker. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 20, 2021 Mar 20, 2021

Copy link to clipboard

Copied

LATEST

One problem can be when one of the Channels has white or black pixels at the Colorpicker position. 

That could result in multiple points being set for the curves at identical positions which does not work out.  

 

Filtering out such conflicting data seems possible but it seems doubtful whether it’s worth the trouble. 

 

Edit: Thinking about it I guess any multiples in any Channel would cause problems. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines