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"
...
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())
Copy link to clipboard
Copied
Thanks!
Just out of curiousity, is there any reason ActionRef returns an RGBColor as "Red Grain Blue"?
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')
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.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Is there way to revert it, so json to descriptor? 😛
Copy link to clipboard
Copied
Trick question? 🙂
Copy link to clipboard
Copied
Seriously, without parsing, just using some secret ActionManager key / property?
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.
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.
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.