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

Photoshop script to invert curves

New Here ,
May 20, 2021 May 20, 2021

Copy link to clipboard

Copied

I want to create a script that will invert/swap the input and output values of all the points in each channel of a selected curves adjustment layer.

 

For example, the script should turn this curve:

 

before.png

 

into this:


after.png

 

This adjustment should be applied to all channels in the curves (RGB, Red, Green, Blue) and to all existing points. I don't have a lot of experience with photoshop scripting but i tried to write it myself and i couldn't figure out where photoshop stores the existing point input and output values. Any help would be appreciated.

TOPICS
Actions and scripting

Views

2.8K

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

correct answers 1 Correct answer

People's Champ , May 20, 2021 May 20, 2021
var raw = get_prop_value("layer", null, "adjustment", 0, "legacyContentData");

var d = get_curves_desc(raw);

edit_adjustment_layer("curves", d, false);

////////////////////////////////////////////////////////////////////////////////////////////
function edit_adjustment_layer(type, data, dlg)
    {
    try { 
        if (type == null || type == undefined) type = get_prop_value("layer", null, "adjustment").getClass(0);

        if (typeof(type) == "string") type = (type.length==4)?charIDToTypeI
...

Votes

Translate

Translate
Adobe
Explorer ,
Jul 20, 2023 Jul 20, 2023

Copy link to clipboard

Copied

 

Unfortunately no...

UNFOTONY_0-1689889102692.png

 

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
People's Champ ,
Jul 20, 2023 Jul 20, 2023

Copy link to clipboard

Copied

quote

 

Unfortunately no...

UNFOTONY_0-1689889102692.png

 


By @UNFOTONY

 

The very last try ).
New stub code at the beginning.
 

 

////////////////////////////////
// False (idle) editing of the adjustment layer 
// in order to remove the "auto" property from the descriptor 
// and get real points.

var d = new ActionDescriptor();
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID("adjustmentLayer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
d.putReference(stringIDToTypeID("null"), r);
var d1 = new ActionDescriptor();
var list = new ActionList();
var d2 = new ActionDescriptor();
var r1 = new ActionReference();
r1.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("composite"));
d2.putReference(stringIDToTypeID("channel"), r1);
d2.putBoolean(stringIDToTypeID("auto"), false);
list.putObject(stringIDToTypeID("curvesAdjustment"), d2);
d1.putList(stringIDToTypeID("adjustment"), list);
d.putObject(stringIDToTypeID("to"), stringIDToTypeID("curves"), d1);
executeAction(stringIDToTypeID("set"), d, DialogModes.NO);

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

var adj = get_prop_value("layer", null, "adjustment", 0);

var adjustment = adj.getList(stringIDToTypeID("adjustment"));
var new_adjustment = new ActionList();

for (var i = 0; i < adjustment.count; i++)
    {
    var curvesAdjustment = adjustment.getObjectValue(i);
    var new_curvesAdjustment = new ActionDescriptor();

    var channel = curvesAdjustment.getReference(stringIDToTypeID("channel"));

    var curve = curvesAdjustment.getList(stringIDToTypeID("curve"));

    var new_curve = new ActionList();

    for (var n = 0; n < curve.count; n++)
        {
        var point = curve.getObjectValue(n);

        var new_point = new ActionDescriptor();

        var x = point.getDouble(stringIDToTypeID("horizontal"));
        var y = point.getDouble(stringIDToTypeID("vertical"));

        new_point.putDouble(stringIDToTypeID("horizontal"), y);
        new_point.putDouble(stringIDToTypeID("vertical"),   x);
    
        new_curve.putObject(stringIDToTypeID("point"), new_point);
        }

    new_curvesAdjustment.putReference(stringIDToTypeID("channel"), channel);
    new_curvesAdjustment.putList(stringIDToTypeID("curve"), new_curve);

    new_adjustment.putObject(stringIDToTypeID("curvesAdjustment"), new_curvesAdjustment);
    }

adj.erase(stringIDToTypeID("adjustment"));
adj.putList(stringIDToTypeID("adjustment"), new_adjustment);

edit_adjustment_layer("curves", adj, false);

////////////////////////////////////////////////////////////////////////////////////////////
function edit_adjustment_layer(type, data, dlg)
    {
    try { 
        if (type == null || type == undefined) type = get_prop_value("layer", null, "adjustment").getClass(0);

        if (typeof(type) == "string") type = (type.length==4)?charIDToTypeID(type):stringIDToTypeID(type);

        var d = new ActionDescriptor();
        var r = new ActionReference();
        r.putEnumerated(stringIDToTypeID("adjustmentLayer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
        d.putReference(stringIDToTypeID("null"), r);

        if (data == null || data == undefined) d.putObject(stringIDToTypeID("to"), type, data);

        var ret = executeAction(stringIDToTypeID("set"), d, dlg==false?DialogModes.NO:DialogModes.ALL);

        if (ret.hasKey(stringIDToTypeID("to"))) 
            ret = ret.getObjectValue(stringIDToTypeID("to"));
        else 
            ret = null;

        return ret;
        }
    catch (e) { alert(e); return null; }
    }

////////////////////////////////////////////////////////////////////////////////////////////
function get_prop_value(class_key, id, prop_key)
    {
    try
        {
        if (typeof(class_key) == "string") class_key = stringIDToTypeID(class_key);
        if (typeof(prop_key)  == "string") prop_key  = stringIDToTypeID(prop_key);

        var r = new ActionReference();    

        if (prop_key != undefined) r.putProperty(stringIDToTypeID("property"), prop_key);

        if (id == undefined || id == null) r.putEnumerated(class_key, stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
        else if (typeof(id) == "string")   r.putName(class_key, id);
        else                               r.putIdentifier(class_key, id);

        var desc;

        if (prop_key == undefined)
            {
            try { return executeActionGet(r); } catch (e) { return undefined; }
            }

        try { desc = executeActionGet(r); } catch (e) { return undefined; }     

        if (!desc.hasKey(prop_key)) return undefined;

        var ret = get_value(desc, prop_key);

        for (var i = 3; i < arguments.length; i++) 
            if (arguments[i] != undefined) ret = get_value(ret, arguments[i]);  

        return ret;

        function get_type(obj, key)
            {
            try 
                {
                if (obj == undefined) return undefined;            

                if (typeof(key) == "string") key = stringIDToTypeID(key);
        
                switch (obj.typename)
                    {
                    case "ActionDescriptor":  
                    case "ActionList"      : return obj.getType(key);
        
                    case "ActionReference" : return obj.getForm();
                    }
                }
            catch (e) { throw(e); }
            }
        
        function get_value(obj, key)
            {
            try 
                {
                if (obj == undefined) return undefined;            

                if (typeof(key) == "string") key = stringIDToTypeID(key);
        
                switch (obj.typename)
                    {
                    case "ActionDescriptor":  
                    case "ActionList"      : return get_desc_value(obj, key);
        
                    case "ActionReference" : return get_ref_value(obj);
                    }
                }
            catch (e) { throw(e); }
            }
        
        function get_desc_value(d, key)
            {
            try 
                {
                if (d == undefined) return undefined;            

                if (typeof(key) == "string") key = stringIDToTypeID(key);
        
                var val; 

                if (d instanceof ActionDescriptor && !d.hasKey(key)) return undefined;

                else if (d instanceof ActionList && key >= d.count) return undefined;

                var type = d.getType(key);
        
                switch (type) 
                    {
                    case DescValueType.ALIASTYPE:        val = d.getPath(key);             break;
                    case DescValueType.BOOLEANTYPE:      val = d.getBoolean(key);          break;
                    case DescValueType.CLASSTYPE:        val = d.getClass(key);            break;
                    case DescValueType.DOUBLETYPE:       val = d.getDouble(key);           break;  
                    case DescValueType.INTEGERTYPE:      val = d.getInteger(key);          break;
                    case DescValueType.LISTTYPE:         val = d.getList(key);             break;
                    case DescValueType.RAWTYPE:          val = d.getData(key);             break;
                    case DescValueType.STRINGTYPE:       val = d.getString(key);           break;
                    case DescValueType.LARGEINTEGERTYPE: val = d.getLargeInteger(key);     break;
                    case DescValueType.REFERENCETYPE:    val = d.getReference(key);        break;
                    case DescValueType.OBJECTTYPE:       val = d.getObjectValue(key);      break;
                    case DescValueType.UNITDOUBLE:       val = d.getUnitDoubleValue(key);  break;
                    case DescValueType.ENUMERATEDTYPE:   val = d.getEnumerationValue(key); break;
                    }
        
                return val;
                }
            catch (e) { throw(e); }
            }
        
        function get_ref_value(r)
            {
            try 
                {
                var val; 
        
                switch (r.getForm())
                    {
                    case ReferenceFormType.CLASSTYPE:  val = r.getDesiredClass();    break;
                    case ReferenceFormType.IDENTIFIER: val = r.getIdentifier();      break;
                    case ReferenceFormType.INDEX:      val = r.getIndex();           break;
                    case ReferenceFormType.NAME:       val = r.getName();            break;
                    case ReferenceFormType.OFFSET:     val = r.getOffset();          break;
                    case ReferenceFormType.ENUMERATED: val = r.getEnumeratedValue(); break;
                    case ReferenceFormType.PROPERTY:   val = r.getProperty();        break;  
                    }
        
                return val;
                }
            catch (e) { throw(e); }
            }
        }   
    catch (e) { throw(e); }
    }

 

 

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 ,
Jul 20, 2023 Jul 20, 2023

Copy link to clipboard

Copied

Same error 😞

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 ,
Jul 20, 2023 Jul 20, 2023

Copy link to clipboard

Copied

Adobe is reading our dialogue and just got the Photoshop Beta 24.7 update. One of the previous versions of the script works in it!

 

Thank you very much!!!

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 ,
Jul 20, 2023 Jul 20, 2023

Copy link to clipboard

Copied

Hurry up. But I found an interesting feature. The script from this message works ONLY after running the last or penultimate script.
That is, I try to run the last script - an error occurs, but this one works after it. And only one specific layer. If you create a new layer, it no longer works.

 

 

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
People's Champ ,
Jul 20, 2023 Jul 20, 2023

Copy link to clipboard

Copied

Yes, strange. Then paste this code at the very beginning of the script that seems to work after the error. The code is surrounded by try-catch and should not raise an error message. But I can't guarantee.
 
 

 

try {
var d = new ActionDescriptor();
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID("adjustmentLayer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
d.putReference(stringIDToTypeID("null"), r);
var d1 = new ActionDescriptor();
var list = new ActionList();
var d2 = new ActionDescriptor();
var r1 = new ActionReference();
r1.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("composite"));
d2.putReference(stringIDToTypeID("channel"), r1);
d2.putBoolean(stringIDToTypeID("auto"), false);
list.putObject(stringIDToTypeID("curvesAdjustment"), d2);
d1.putList(stringIDToTypeID("adjustment"), list);
d.putObject(stringIDToTypeID("to"), stringIDToTypeID("curves"), d1);
executeAction(stringIDToTypeID("set"), d, DialogModes.NO);
} catch(e) { }

 

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 ,
Jul 20, 2023 Jul 20, 2023

Copy link to clipboard

Copied

LATEST

The error will be raised by the last script that runs first. I tried to paste the code into it, but the error still remained. I tried to insert the code into the following script, but the error also remained.

It's strange that the former scripts work well after using the latter.

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