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

How to read Layer Effects?

New Here ,
Apr 14, 2008 Apr 14, 2008
I'd like to be able to use PhotoShop as an authoring tool for the artists at our game development company. The scripting has been a godsend for allowing them to specify layout and positioning of various art assets.

I'm stuck on getting at the drop shadow effect on a layer. I'd like to be able to read and output whether a drop shadow is being used, and if it is being used, the angle and distance of the drop shadow.

I've come across lots of samples that use "executeAction" to turn effects on and off, but I have not come across anything that allows me to access the values in a pre-existing effect.

Any leads would be greatly appreciated.
TOPICS
Actions and scripting
1.4K
Translate
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
Explorer ,
Apr 14, 2008 Apr 14, 2008
Brennan_McTernan@adobeforums.com wrote:
> I'm stuck on getting at the drop shadow effect on a layer. I'd like to be able to read and output whether a drop shadow is being used, and if it is being used, the angle and distance of the drop shadow.

Unless I'm reading my xml wrong, it should be something close to this:

cTID = function(s) { return app.charIDToTypeID(s); };

// returns the ActionDescriptor for the active layer of the active doc
function getLayerDescriptor() {
var ref = new ActionReference();
ref.putEnumerated(cTID("Lyr "), cTID("Ordn"), cTID("Trgt"));
return executeActionGet(ref)
};

// returns the ActionDescriptor for the layer style of the active layer
// of the active doc
function getLayerStyleDescriptor() {
var desc = getLayerDescriptor();

return desc.hasKey(cTID('Lefx')) ?
desc.getObjectValue(cTID('Lefx') : undefined;
};

var ldesc = getLayerStyleDescriptor();

if (ldesc) {
// Get the drop shadow descriptor if there is one.
var drSh = ldesc.hasKey(cTID('DrSh')) ?
ldesc.getObjectValue(cTID('DrSh') : undefined;
if (drSh) {
var angle = drSh.getUnitDoubleValue(cTID('lagl'));
var angleType = drSh.getUnitDoubleType(cTID('lagl'));

var dist = drSh.getUnitDoubleValue(cTID('Dstn'));
var distType = drSh.getUnitDoubleType(cTID('Dstn'));
}
}


-X
--
for photoshop scripting solutions of all sorts
contact: xbytor@gmail.com
Translate
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
New Here ,
Apr 15, 2008 Apr 15, 2008
Thanks for this feedback.

In my sample psd file, I have a text layer with a drop shadow layer style added to it.
I make this layer active and run this script (with some syntax repairs), but the call "desc.hasKey(cTID('Lefx'))" seems to be false.

You mention "Unless I'm reading my xml wrong".
Is there an xml reference that talks about properties?
The JavaScript reference doesn't get into Layer Effect properties.
Translate
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 ,
Apr 15, 2008 Apr 15, 2008
Brennan_McTernan@adobeforums.com wrote:

> I make this layer active and run this script (with some syntax repairs), but the call "desc.hasKey(cTID('Lefx'))" seems to be false.

OK. I'll actually test it again and post a fixed rev.

> You mention "Unless I'm reading my xml wrong".

In my xtools JS library for PS, I have scripts that generate XML for various PS
internals including what's in a layer and the what's actually in an action file.
For something like this, I created a layer with a drop shadow effect and ran one
of these scripts to dump the XML for the layer.


> Is there an xml reference that talks about properties?

No. The XML representation is my own creation. It's complete enough that I can
generate XML for an action, make some mods to the XML and regenerate the Action
with those mods.


> The JavaScript reference doesn't get into Layer Effect properties.

There is not support in the PSJS DOM for layer effects, along with lots of other
bits.

I'll post a revised script later.

-X
--
for photoshop scripting solutions of all sorts
contact: xbytor@gmail.com
Translate
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 ,
Apr 15, 2008 Apr 15, 2008
This script works. I added some handy alerts to show you what it finds.

-X


cTID = function(s) { return app.charIDToTypeID(s); };

id2char = function(s) {
_numberToAscii = function(n) {
if (isNaN(n)) {
return n;
}
var str = '';
str += String.fromCharCode(n >> 24);
str += String.fromCharCode((n >> 16) & 0xFF);
str += String.fromCharCode((n >> 8) & 0xFF);
str += String.fromCharCode(n & 0xFF);

return str.match(/^\w{4}$/) ? str : n;
};

if (isNaN(Number(s))){
return '';
}
var v;

// Use every mechanism available to map the typeID
var lvl = $.level;
$.level = 0;
try {
if (!v) {
try { v = app.typeIDToCharID(s); } catch (e) {}
}
if (!v) {
try { v = app.typeIDToStringID(s); } catch (e) {}
}
} catch (e) {
}
$.level = lvl;
if (!v) {
v = _numberToAscii(s);
}
return v ? v : s;
};

// returns the ActionDescriptor for the active layer of the active doc
function getLayerDescriptor() {
var ref = new ActionReference();
ref.putEnumerated(cTID("Lyr "), cTID("Ordn"), cTID("Trgt"));
return executeActionGet(ref)
};

// returns the ActionDescriptor for the layer style of the active layer
// of the active doc
function getLayerStyleDescriptor() {
var desc = getLayerDescriptor();

return desc.hasKey(cTID('Lefx')) ?
desc.getObjectValue(cTID('Lefx')) : undefined;
};

function main() {
var ldesc = getLayerStyleDescriptor();

if (ldesc) {
// Get the drop shadow descriptor if there is one.
var drSh = ldesc.hasKey(cTID('DrSh')) ?
ldesc.getObjectValue(cTID('DrSh')) : undefined;
if (drSh) {
var angle = drSh.getUnitDoubleValue(cTID('lagl'));
var angleType = drSh.getUnitDoubleType(cTID('lagl'));

var dist = drSh.getUnitDoubleValue(cTID('Dstn'));
var distType = drSh.getUnitDoubleType(cTID('Dstn'));

var str = "angle: " + angle + ' ' + id2char(angleType) + '\n';
str += "distance: " + dist + ' ' + id2char(distType);

alert(str);

} else {
alert("No drop shadow effects found");
}
} else {
alert("No layer effects found");
}
};


main();
Translate
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
New Here ,
Apr 15, 2008 Apr 15, 2008
Wow, you've really been terrific with this! Thank you!

I wonder if I'm seeing a CS2 vs CS3 issue or something. I'm still getting a "No layer effects found".
Here's how I've made my test effect (in CS2):
1) I make a simple image. (File->new)
2) I add a layer
3) I make a small rectangular selection and fill it with foreground color.
4) I right-click on the layer and select Drop Shadow in the Blending Options of the dialog that pops up (with OK).
This creates a Drop Shadow Layer Effect that doesn't seem to be findable!
I realize I'm pushing my luck, but any other thoughts?
Thanks again.
Translate
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 ,
Apr 15, 2008 Apr 15, 2008
Brennan_McTernan@adobeforums.com wrote:
> Wow, you've really been terrific with this! Thank you!
>
> I wonder if I'm seeing a CS2 vs CS3 issue or something. I'm still getting a "No layer effects found".

You got it! I'd actually forgotten that this wasn't available in CS2. It is in CS3.

There is yet another solution. You can save the style to disk as .asl file then
parse the binary .asl file for your data, a complicated process.

Fortunately, I've implemented all of that. There is a script xlib/Styles.js in
xtools that does the heavy lifting (along with several other xtools/lib
scripts). You just make a call like:
var ldesc = Styles.getLayerStyleDescriptor(doc, layer);

to get the layer effects descriptor then access the descriptor like I did in the
script I posted.

You can find xtools at ps-scripts.sourceforge.org/xtools.html

-X
--
for photoshop scripting solutions of all sorts
contact: xbytor@gmail.com
Translate
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 ,
Apr 15, 2008 Apr 15, 2008
X posted the answer as I was typing this post so never mind
Translate
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
New Here ,
Apr 17, 2008 Apr 17, 2008
So "var ldesc = Styles.getLayerStyleDescriptor(doc, layer);" is almost perfect for CS2.
I can access position data, etc. But
I noticed that the drop shadow angle didn't match what I had in the dialog box. When I run the ScriptListener, it looks like this angle is stored as the global light angle ("gagl") instead of the local light angle ("lagl")
I did some hunting int the xlib js files and didn't find a place where I could make this fix. Can you direct me to this?

- Brennan
Translate
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 ,
Apr 17, 2008 Apr 17, 2008
LATEST
You can check the value of the key 'uglg' of the drop shadow descriptor. If it is set to true then 'lagl' and 'gagl' are the same.

If that value is false then the drop shadow doesn't use the global angle. Either way 'lagl' should match that angle from the dialog.

The value of 'gagl' is found in ldesc.getUnitDouble( charIDToTypeID( "gagl" )

It is also found as the key 'gblA' in the app descriptor.

Mike
Translate
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