Highlighted

How to get the fill color of a vector or mask in scripting?

Engaged ,
Jun 12, 2020

Copy link to clipboard

Copied

Hello all. Recently made myself an ActionReference translator that essentially creates a simplified object of a given layer to make it much easier (in my opinion) to work with. As far as I can tell, it works for everything but in using it for a given vector I get results like this:

{
  "layer": "test",
  "color": "none",
  "visible": true,
  "mode": "normal",
  "opacity": 255,
  "layerID": 18,
  "itemIndex": 2,
  "count": 2,
  "preserveTransparency": false,
  "layerFXVisible": false,
  "globalAngle": 90,
  "background": false,
  "layerSection": 4187,
  "layerLocking": {
    "protectTransparency": false,
    "protectComposite": false,
    "protectPosition": false,
    "protectArtboardAutonest": false,
    "protectAll": false
  },
  "group": false,
  "targetChannels": { "count": 3, "typename": "ActionList" },
  "visibleChannels": { "count": 3, "typename": "ActionList" },
  "channelRestrictions": { "count": 3, "typename": "ActionList" },
  "fillOpacity": 255,
  "hasUserMask": false,
  "hasVectorMask": true,
  "proportionalScaling": false,
  "layerKind": 4,
  "hasFilterMask": false,
  "userMaskDensity": 255,
  "userMaskFeather": 0,
  "vectorMaskDensity": 255,
  "vectorMaskFeather": 0,
  "adjustment": { "count": 1, "typename": "ActionList" },
  "bounds": {
    "top": 300,
    "left": 300,
    "bottom": 500,
    "right": 500,
    "width": 200,
    "height": 200
  },
  "boundsNoEffects": {
    "top": 300,
    "left": 300,
    "bottom": 500,
    "right": 500,
    "width": 200,
    "height": 200
  },
  "boundsNoMask": {
    "top": 0,
    "left": 0,
    "bottom": 1000,
    "right": 1500,
    "width": 1500,
    "height": 1000
  },
  "pathBounds": {
    "pathBounds": {
      "top": 300,
      "left": 300,
      "bottom": 500,
      "right": 500
    }
  },
  "useAlignedRendering": true,
  "generatorSettings": {},
  "AGMStrokeStyleInfo": {
    "strokeStyleVersion": 2,
    "strokeEnabled": true,
    "fillEnabled": true,
    "strokeStyleLineWidth": 20,
    "strokeStyleLineDashOffset": 0,
    "strokeStyleMiterLimit": 100,
    "strokeStyleLineCapType": 2332,
    "strokeStyleLineJoinType": 2336,
    "strokeStyleLineAlignment": 2339,
    "strokeStyleScaleLock": false,
    "strokeStyleStrokeAdjust": false,
    "strokeStyleLineDashSet": { "count": 0, "typename": "ActionList" },
    "strokeStyleBlendMode": "normal",
    "strokeStyleOpacity": 100,
    "strokeStyleContent": {
      "color": "RGBColor(255,0,0)"
    },
    "strokeStyleResolution": 72
  },
  "keyOriginType": { "count": 1, "typename": "ActionList" },
  "fillEnabled": true,
  "animationProtection": {
    "animationUnifyPosition": false,
    "animationUnifyEffects": false,
    "animationUnifyVisibility": false,
    "animationPropagate": true
  },
  "artboard": {
    "artboardRect": {
      "top": 0,
      "left": 0,
      "bottom": 0,
      "right": 0
    },
    "guideIDs": { "count": 0, "typename": "ActionList" },
    "artboardPresetName": "",
    "color": "RGBColor(255,255,255)",
    "artboardBackgroundType": 1
  },
  "artboardEnabled": false,
  "vectorMaskEnabled": true,
  "vectorMaskEmpty": false,
  "textWarningLevel": 0
}

Noticeably it doesn't provide the fill color. I have a green rectangle with a red stroke in PS, but it I don't see any green color value here. The "color" StringID of a layer ActionReference always returns "none" even before I create a readable string format. There's a clear key object for the stroke, but nothing for a fill?

Just to be clear, I'm not looking to create a fill on a vector -- I'm trying to read the current fill of a given vector. Does any one have the charID chain to access this info? Is the issue in my translating function missing keys, or is there any other way to do this?

Thanks!

look into adjustment ActionList:

 

"adjustment": [
        {
            "_obj": "solidColorLayer",
            "color": {
                "_obj": "RGBColor",
                "blue": 0,
                "grain": 255,
                "red": 255
            }
        }
    ]

 

P.S. you can convert the entire descriptor to an object (or any part of it) without much effort in a similar way:

 

var s2t =stringIDToTypeID;
(r = new ActionReference()).putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
(d = new ActionDescriptor()).putObject(s2t("object"), s2t("object"), executeActionGet(r));
eval ('var obj = ' + executeAction(s2t("convertJSONdescriptor"), d).getString(s2t("json")));
alert (obj.toSource())

 

 

TOPICS
Actions and scripting

Views

356

Likes

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

How to get the fill color of a vector or mask in scripting?

Engaged ,
Jun 12, 2020

Copy link to clipboard

Copied

Hello all. Recently made myself an ActionReference translator that essentially creates a simplified object of a given layer to make it much easier (in my opinion) to work with. As far as I can tell, it works for everything but in using it for a given vector I get results like this:

{
  "layer": "test",
  "color": "none",
  "visible": true,
  "mode": "normal",
  "opacity": 255,
  "layerID": 18,
  "itemIndex": 2,
  "count": 2,
  "preserveTransparency": false,
  "layerFXVisible": false,
  "globalAngle": 90,
  "background": false,
  "layerSection": 4187,
  "layerLocking": {
    "protectTransparency": false,
    "protectComposite": false,
    "protectPosition": false,
    "protectArtboardAutonest": false,
    "protectAll": false
  },
  "group": false,
  "targetChannels": { "count": 3, "typename": "ActionList" },
  "visibleChannels": { "count": 3, "typename": "ActionList" },
  "channelRestrictions": { "count": 3, "typename": "ActionList" },
  "fillOpacity": 255,
  "hasUserMask": false,
  "hasVectorMask": true,
  "proportionalScaling": false,
  "layerKind": 4,
  "hasFilterMask": false,
  "userMaskDensity": 255,
  "userMaskFeather": 0,
  "vectorMaskDensity": 255,
  "vectorMaskFeather": 0,
  "adjustment": { "count": 1, "typename": "ActionList" },
  "bounds": {
    "top": 300,
    "left": 300,
    "bottom": 500,
    "right": 500,
    "width": 200,
    "height": 200
  },
  "boundsNoEffects": {
    "top": 300,
    "left": 300,
    "bottom": 500,
    "right": 500,
    "width": 200,
    "height": 200
  },
  "boundsNoMask": {
    "top": 0,
    "left": 0,
    "bottom": 1000,
    "right": 1500,
    "width": 1500,
    "height": 1000
  },
  "pathBounds": {
    "pathBounds": {
      "top": 300,
      "left": 300,
      "bottom": 500,
      "right": 500
    }
  },
  "useAlignedRendering": true,
  "generatorSettings": {},
  "AGMStrokeStyleInfo": {
    "strokeStyleVersion": 2,
    "strokeEnabled": true,
    "fillEnabled": true,
    "strokeStyleLineWidth": 20,
    "strokeStyleLineDashOffset": 0,
    "strokeStyleMiterLimit": 100,
    "strokeStyleLineCapType": 2332,
    "strokeStyleLineJoinType": 2336,
    "strokeStyleLineAlignment": 2339,
    "strokeStyleScaleLock": false,
    "strokeStyleStrokeAdjust": false,
    "strokeStyleLineDashSet": { "count": 0, "typename": "ActionList" },
    "strokeStyleBlendMode": "normal",
    "strokeStyleOpacity": 100,
    "strokeStyleContent": {
      "color": "RGBColor(255,0,0)"
    },
    "strokeStyleResolution": 72
  },
  "keyOriginType": { "count": 1, "typename": "ActionList" },
  "fillEnabled": true,
  "animationProtection": {
    "animationUnifyPosition": false,
    "animationUnifyEffects": false,
    "animationUnifyVisibility": false,
    "animationPropagate": true
  },
  "artboard": {
    "artboardRect": {
      "top": 0,
      "left": 0,
      "bottom": 0,
      "right": 0
    },
    "guideIDs": { "count": 0, "typename": "ActionList" },
    "artboardPresetName": "",
    "color": "RGBColor(255,255,255)",
    "artboardBackgroundType": 1
  },
  "artboardEnabled": false,
  "vectorMaskEnabled": true,
  "vectorMaskEmpty": false,
  "textWarningLevel": 0
}

Noticeably it doesn't provide the fill color. I have a green rectangle with a red stroke in PS, but it I don't see any green color value here. The "color" StringID of a layer ActionReference always returns "none" even before I create a readable string format. There's a clear key object for the stroke, but nothing for a fill?

Just to be clear, I'm not looking to create a fill on a vector -- I'm trying to read the current fill of a given vector. Does any one have the charID chain to access this info? Is the issue in my translating function missing keys, or is there any other way to do this?

Thanks!

look into adjustment ActionList:

 

"adjustment": [
        {
            "_obj": "solidColorLayer",
            "color": {
                "_obj": "RGBColor",
                "blue": 0,
                "grain": 255,
                "red": 255
            }
        }
    ]

 

P.S. you can convert the entire descriptor to an object (or any part of it) without much effort in a similar way:

 

var s2t =stringIDToTypeID;
(r = new ActionReference()).putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
(d = new ActionDescriptor()).putObject(s2t("object"), s2t("object"), executeActionGet(r));
eval ('var obj = ' + executeAction(s2t("convertJSONdescriptor"), d).getString(s2t("json")));
alert (obj.toSource())

 

 

TOPICS
Actions and scripting

Views

357

Likes

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
Jun 12, 2020 0
Enthusiast ,
Jun 12, 2020

Copy link to clipboard

Copied

look into adjustment ActionList:

 

"adjustment": [
        {
            "_obj": "solidColorLayer",
            "color": {
                "_obj": "RGBColor",
                "blue": 0,
                "grain": 255,
                "red": 255
            }
        }
    ]

 

P.S. you can convert the entire descriptor to an object (or any part of it) without much effort in a similar way:

 

var s2t =stringIDToTypeID;
(r = new ActionReference()).putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
(d = new ActionDescriptor()).putObject(s2t("object"), s2t("object"), executeActionGet(r));
eval ('var obj = ' + executeAction(s2t("convertJSONdescriptor"), d).getString(s2t("json")));
alert (obj.toSource())

 

 

Likes

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
Reply
Loading...
Jun 12, 2020 1
Engaged ,
Jun 15, 2020

Copy link to clipboard

Copied

Thanks!

 

Just out of curiousity, is there any reason ActionRef returns an RGBColor as "Red Grain Blue"?

Likes

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
Reply
Loading...
Jun 15, 2020 0
Enthusiast ,
Jun 15, 2020

Copy link to clipboard

Copied

I suppose that, when only 4-character charIDs were used (green was designated as 'Grn '). Perhaps, for optimization purposes or as a result of an error, the same ID was assigned to the Grain parameter in the filters. After stringID was added, it became possible to split green and grain, but the old notation remained for compatibility purposes. i.e

 

 stringIDToTypeID('green') == stringIDToTypeID('grain')

 

 

Likes

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
Reply
Loading...
Jun 15, 2020 0
Adobe Community Professional ,
Jun 16, 2020

Copy link to clipboard

Copied

'Grain' as 'Green' is not only exception, there're many others, but this one is most known. Probably when character is being converted to string it reads 1st key assigned for that, so 'Grain' in this case, which may be on top of 'Grn ' items list.

Likes

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
Reply
Loading...
Jun 16, 2020 1
Adobe Community Professional ,
Jun 16, 2020

Copy link to clipboard

Copied

Likes

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
Reply
Loading...
Jun 16, 2020 1
Adobe Community Professional ,
Oct 05, 2020

Copy link to clipboard

Copied

Is there way to revert it, so json to descriptor? 😛

Likes

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
Reply
Loading...
Oct 05, 2020 1
Enthusiast ,
Oct 05, 2020

Copy link to clipboard

Copied

Trick question? 🙂 

Likes

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
Reply
Loading...
Oct 05, 2020 0
Adobe Community Professional ,
Oct 05, 2020

Copy link to clipboard

Copied

Seriously, without parsing, just using some secret ActionManager key / property?

Likes

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
Reply
Loading...
Oct 05, 2020 0
Enthusiast ,
Oct 05, 2020

Copy link to clipboard

Copied

Well, besides the key / property, there is also an object / property type. That is, if you add all the necessary data to the object being created, then it will.
I tried to use for this purpose JSON generated by executeAction (s2t ('convertJSONdescriptor'), d) .getString (s2t ('json')) - there is good detail and in most cases it is possible to restore the structure of the descriptor, but everything depends on the lack of types for numerical values - it is impossible to distinguish an integer from a double in the convertJSONdescriptor output, let alone any units.

Likes

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
Reply
Loading...
Oct 05, 2020 1
Enthusiast ,
Oct 05, 2020

Copy link to clipboard

Copied

that is, even if the built-in tools do not give full information about the descriptor, then there is hardly a function that allows you to collect it back without parsing.

Likes

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
Reply
Loading...
Oct 05, 2020 0
Adobe Community Professional ,
Oct 05, 2020

Copy link to clipboard

Copied

There are toStream() and fromStream() functions I like to use. Too bad some binary information of for ex. psd documents / layers don't cover them, but are written to file other way. It'd be so easy to use fromStream() on .psd instead of parsing them and yeilding needed data by other methods.

Likes

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
Reply
Loading...
Oct 05, 2020 1