Adjustment Layer Getting Preset Kind

I am trying to get the PresetKind to establish if an adjustment layer specifically curves have no adjustments applied to them. I made the following getter but it doesn’t want to work for me. Any help on where the bug might be would be much appreciated

const app = require("photoshop").app;
const batchPlay = require("photoshop").action.batchPlay;

Object.defineProperty(require("photoshop").app.Layer.prototype, 
"presetKindType",
{
    get: () =>{
        const result = batchPlay(
            [
               {
                  _obj: "get",
                  _target: [
                     {
                        _property: "presetKindType"
                        
                     },
                     {
                        _ref: "adjustmentLayer",
                        _enum: "ordinal",
                         _value: "targetEnum"
                     }
                  ],
                  _options: {
                     dialogOptions: "dontDisplay"
                  }
               }
            ],{
               synchronousExecution: true,
               modalBehavior: "fail"
            });
            return result[0].presetKindType._value; 
    }
})

What do you mean by doesn’t work?
What’s the actual result? What’s the expected result?

Id like to get the result of the enumeration value i.e. “presetKindCustom” to establish if the curve has any points or is empty…

When i run it i get the response " The command “Get” is not currently available."

Usually it’s because of the wrong descriptor or more likely wrong property you try to interact with. In this case it’s probably presetKindType or adjustmentLayer (did you try just layer?). What does Alchemist show for that layer property?

I know, this is a very annoying error which doesn’t actually tell you anything useful. Same happens with set or any other _obj

It was quite tricky to get the code out of alchemist took a couple of goes. see below

const batchPlay = require("photoshop").action.batchPlay;

const result = await batchPlay(
[
   {
      _obj: "set",
      _target: [
         {
            _ref: "adjustmentLayer",
            _enum: "ordinal",
            _value: "targetEnum"
         }
      ],
      to: {
         _obj: "curves",
         presetKind: {
            _enum: "presetKindType",
            _value: "presetKindCustom"
         },
         adjustment: [
            {
               _obj: "curvesAdjustment",
               channel: {
                  _ref: "channel",
                  _enum: "channel",
                  _value: "composite"
               },
               curve: [
                  {
                     _obj: "paint",
                     horizontal: 0,
                     vertical: 0
                  },
                  {
                     _obj: "paint",
                     horizontal: 140,
                     vertical: 77
                  },
                  {
                     _obj: "paint",
                     horizontal: 255,
                     vertical: 255
                  }
               ]
            }
         ]
      },
      _options: {
         dialogOptions: "dontDisplay"
      }
   }
],{
   synchronousExecution: false,
   modalBehavior: "fail"
});
const batchPlay = require("photoshop").action.batchPlay;

const result = await batchPlay(
[
   {
      _obj: "make",
      _target: [
         {
            _ref: "adjustmentLayer"
         }
      ],
      using: {
         _obj: "adjustmentLayer",
         type: {
            _obj: "curves",
            presetKind: {
               _enum: "presetKindType",
               _value: "presetKindDefault"
            }
         }
      },
      _options: {
         dialogOptions: "dontDisplay"
      }
   }
],{
   synchronousExecution: false,
   modalBehavior: "fail"
});

I can’t seem to read the property via Alchemist inspector… I can only find it using the listener when creating a curve layer. I tried swapping out adjustmentLayer for Layer but to no avail

Not sure if it’s the only way, but you can get this from layers json property.

    {
        _obj: "get",
        _target: [
            {_property: "json"},
            { _ref: "layer",_enum: "ordinal", _value: "targetEnum"},
        ],
        _options: {dialogOptions: "dontDisplay"}
    }

There you’ll need to JSON.parse(propertyValue) and you’ll find layers. Then you could recursively iterate through these layers and find the one you need by ID. You’ll get something like that:

        {
          "id": 18,
          "index": 4,
          "type": "adjustmentLayer",
          "name": "Curves 1",
          "bounds": {"top": 0, "left": 0, "bottom": 2048, "right": 3072},
          "visible": true,
          "clipped": false,
          "adjustment": {
            "presetKind": "presetKindCustom",
            "adjustment": [
              {
                "channel": "composite",
                "curve": [
                  {"horizontal": 0, "vertical": 0},
                  {"horizontal": 147, "vertical": 106},
                  {"horizontal": 219, "vertical": 136},
                  {"horizontal": 255, "vertical": 255}
                ]
              }
            ],
            "class": "curves"
          },
          "mask": {
            "bounds": {"top": 0, "left": 0, "bottom": 2048, "right": 3072},
            "extendWithWhite": true
          },
          "generatorSettings": false
        }

Just checked and even if you reset all points on the curve, it still gives custom, but without adjustment:

        {
          "id": 18,
          "index": 4,
          "type": "adjustmentLayer",
          "name": "Curves 1",
          "bounds": {"top": 0, "left": 0, "bottom": 2048, "right": 3072},
          "visible": true,
          "clipped": false,
          "adjustment": {
            "presetKind": "presetKindCustom",
            "class": "curves"
          },
          "mask": {
            "bounds": {"top": 0, "left": 0, "bottom": 2048, "right": 3072},
            "extendWithWhite": true
          },
          "generatorSettings": false
        }

Freshly created layer has exact same structure, but "presetKind": "presetKindDefault"

Thats really useful, thanks so much for your help. Interesting the presetKind doesn’t revert to default.

Came up with this in the end using your Json idea

     const batchPlay = require("photoshop").action.batchPlay;
     function getCurve() {
      const result = batchPlay(
          [{
              "_obj": "get",
              "_target": [{
                      "_property": "json"
                  },
                  {
                      "_ref": "layer",
                      "_enum": "ordinal",
                      "_value": "targetEnum"
                  },
                  {
                      "_ref": "document",
                      "_enum": "ordinal",
                      "_value": "targetEnum"
                  }
              ],
              "_options": {
                  "dialogOptions": "dontDisplay"
              }
          }], {
              "synchronousExecution": true,
              "modalBehavior": "fail"
          });
      const getCurve = JSON.parse(result[0].json).layers[0].adjustment.presetKind;
      console.log(getCurve)
  }

![Screenshot 2022-04-28 at 13.35.10|476x292](upload://xkPcXRSlG0D2eO2tfQhvqVH54Mp.png)


```These are the sort of results it brings

I intentionally mentioned recursive iteration to get a layer. My layers stucture is something like:

Group 1
 |- Layer 1
 '- Layer 2
Layer 3
Layer 4
Group 2
 |- Layer 5
 |- Curves << ACTIVE LAYER I TRY TO GET
 '- Layer 6
Layer 7
Background

And JSON.parse(result[0].json) gave me structure like this:

Group 1
Group 2
 '- Curves

Ah ha i see, ill have a go

I’m guessing something like this?

const batchPlay = require("photoshop").action.batchPlay;
    
      const result = batchPlay(
          [{
              "_obj": "get",
              "_target": [{
                      "_property": "json"
                  },
                  {
                      "_ref": "document",
                      "_enum": "ordinal",
                      "_value": "targetEnum"
                  }
              ],
              "_options": {
                  "dialogOptions": "dontDisplay"
              }
          }], {
              "synchronousExecution": true,
              "modalBehavior": "fail"
          });
          let jsonProp = result[0].json;
          console.log("jsonProp", jsonProp)
          let jsonData = JSON.parse(jsonProp);
          console.log("jsonData", jsonData)
     const lyrs = jsonData.layers
     console.log(lyrs)

for(i = 0; i < lyrs.length; i++){
 //  console.log(lyrs[i].type)
   if(lyrs[i].type == "adjustmentLayer"){

      console.log(lyrs[i].adjustment.presetKind)
      console.log(lyrs[i].id)
   }


}```

I would write a proper recursive function to search through the whole tree until it hits the layer you’re looking for. I will need this also, so if you can wait a bit, I might provide it in a day or sooner. But if it doesn’t return layers, that are located inside the layer I’m looking for, then maybe this would not be an option for me. I will check this later

That would be wonderful, Many thanks for your help

OK, so for me this approach is a no go, because that JSON does not contain children layers, but anyway I quickly wrote small function, which allows you to search for an object in the array with similar structure. This will return first match or null if not found:

const testArray = [
    {
        "name": "Title 1", "id": "id01", "children": [
            {"name": "Title 5", "id": "id05"},
            {"name": "Title 6", "id": "id06"},
            {"name": "Title 7", "id": "id07"},
            {
                "name": "Title 3", "id": "id08", "children": [
                    {"name": "Title 8", "id": "id08"},
                    {"name": "Title 9", "id": "id09"},
                    {"name": "Title 10", "id": "id10"},
                    {"name": "Title 11", "id": "id11"},
                ]
            },
        ]
    },
    {"name": "Title 2", "id": "id02"},
    {"name": "Title 3", "id": "id03"},
    {
        "name": "Title 3", "id": "id04", "children": [
            {"name": "Title 1", "id": "id12"},
            {"name": "Title 8", "id": "id13"},
            {"name": "Title 3", "id": "id14"},
            {"name": "Title 3", "id": "id15"},
        ]
    },
]

const searchRecursive = ({items, childrenKey, searchKey, searchValue}) => {
    let result = null

    for (const item of items) {
        if (item[searchKey] === searchValue) {
            result = item
            break
        }

        if (!result && typeof item[childrenKey] === "object" && item[childrenKey].length) {
            result = searchRecursive({items: item[childrenKey], childrenKey, searchKey, searchValue})
        }
    }

    return result
}

console.log(searchRecursive({
    items: testArray,
    childrenKey: "children",
    searchKey: "id",
    searchValue: "id02",
})) // { name: 'Title 2', id: 'id02' }

console.log(searchRecursive({
    items: testArray,
    childrenKey: "children",
    searchKey: "name",
    searchValue: "Title 8",
})) // {"name": "Title 8", "id": "id08"}

console.log(searchRecursive({
    items: testArray,
    childrenKey: "children",
    searchKey: "id",
    searchValue: "id12",
})) // {"name": "Title 1", "id": "id12"}

console.log(searchRecursive({
    items: testArray,
    childrenKey: "children",
    searchKey: "name",
    searchValue: "Title 8",
})) // { name: 'Title 8', id: 'id08' }

console.log(searchRecursive({
    items: testArray,
    childrenKey: "children",
    searchKey: "name",
    searchValue: "Title 88",
})) // null

console.log(searchRecursive({
    items: testArray,
    childrenKey: "nonExistantKey",
    searchKey: "name",
    searchValue: "Title 8",
})) // null

What if you get json property of layer instead of document?

In my example here it is with layer and for whatever reason it returns structure like mentioned here :man_shrugging:

Json property has additional flags see: Photoshop Kevlar API Additions for Generator · adobe-photoshop/generator-core Wiki · GitHub (needs to be transformed for batchPlay)

Alchemist is using it here: alchemist/GetInfo.ts at master · jardicc/alchemist · GitHub when you select “generator” option in inspector.

1 Like