Question

Is there any way to get text(or any other) layer shadow params in Adobe Photoshop CS5 using ExtendScript for further convertion to CSS3 like text string?

Thanks!

Was it helpful?

Solution

There is a way.

You have to use the ActionManager:

var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
var desc = executeActionGet(ref).getObjectValue(stringIDToTypeID('layerEffects')).getObjectValue(stringIDToTypeID('dropShadow'));
desc.getUnitDoubleValue(stringIDToTypeID('distance'))

Where "dropShadow" is the layereffect you want to read and for example "distance" is the parameter that will be returned. Other layereffects and parameters are only known as eventids. Look in the documentation (bad documented) if you need other eventids.

The next AM-Code will check if there is a layerstyle shadow.

var res = false;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
var hasFX =  executeActionGet(ref).hasKey(stringIDToTypeID('layerEffects'));
if ( hasFX ){
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
res = executeActionGet(ref).getObjectValue(stringIDToTypeID('layerEffects')).hasKey(stringIDToTypeID('dropShadow'));
    }
return res;

This will explain http://forums.adobe.com/thread/714406 more.

If you find a way to SET the shadow, without setting other params, let me know...

OTHER TIPS

Probably not the answer you're looking for but there is really no way to access the individual properties of layer styles from extendscript. The only method in the API (as of CS6) that references layer styles is ArtLayer.applyStyle(name). You actually have to create a style in Photoshop and save to the palette by name in order to use this.

The only thing I can think of is to actually parse the .asl files found in adobe/Adobe Photoshop/presets/styles/ using C/C++. These files contain several layer styles saved in a proprietary format. I haven't found any libraries to parse these files but they may exist.

If you have Photoshop CS6.1 (or later), you can check out the implementation of the "Copy CSS to Clipboard" feature to see how to access the drop shadow parameters.

On Windows, the source code for this is in

Adobe Photoshop CS6\Required\CopyCSSToClipboard.jsx

On the Mac, the source code is in:

Adobe Photoshop CS6/Adobe Photoshop CS6.app/Contents/Required/CopyCSSToClipboard.jsx

(if you're looking in the Finder on the Mac, you'll need to control-click on the Photoshop app icon and select "Show Package Contents" to get to the Contents/Required folder).

Look for the routine cssToClip.addDropShadow for an example of how to extract the information. If you want to use routines from CopyCSSToClipboard.jsx in your own code, add the following snippet to your JSX file:

runCopyCSSFromScript = true; 
if (typeof cssToClip == "undefined")
    $.evalFile( app.path + "/" + localize("$$$/ScriptingSupport/Required=Required") + "/CopyCSSToClipboard.jsx" );

Also, at the bottom of CopyCSSToClipboard.jsx, there are sample calls to cssToClip.dumpLayerAttr. This is a useful way to explore parameters you may want to access from your scripts that aren't accessible from the Photoshop DOM.

Be forewarned that code in the Required folder is subject to change in future versions.

I was able to make an ActionPrinter method that dumps out a tree of all the data in an action using C# and the photoshop COM wrapper.

The PrintCurrentLayer method will dump all the data in a layer, including all of the Layer Effects data.

    static void PrintCurrentLayer(Application ps)
    {
        var action = new ActionReference();
        action.PutEnumerated(ps.CharIDToTypeID("Lyr "), ps.CharIDToTypeID("Ordn"), ps.CharIDToTypeID("Trgt"));
        var desc = ps.ExecuteActionGet(action);//.GetObjectValue(ps.StringIDToTypeID("layerEffects"));//.getObjectValue(ps.StringIDToTypeID('dropShadow'));
        ActionPrinter(desc);
    }

    static void ActionPrinter(ActionDescriptor action)
    {
        for (int i = 0; i < action.Count; i++)
        {
            var key = action.GetKey(i);

            if (action.HasKey(key))
            {
                //var charId = action.Application.TypeIDToCharID((int)key);
                //Debug.WriteLine(charId);

                switch (action.GetType(key))
                {
                    case PsDescValueType.psIntegerType:
                        Debug.WriteLine("{0}: {1}", (PSConstants)key, action.GetInteger(key));
                        break;
                    case PsDescValueType.psStringType:
                        Debug.WriteLine("{0}: \"{1}\"", (PSConstants)key, action.GetString(key));
                        break;
                    case PsDescValueType.psBooleanType:
                        Debug.WriteLine("{0}: {1}", (PSConstants)key, action.GetBoolean(key));
                        break;
                    case PsDescValueType.psDoubleType:
                        Debug.WriteLine("{0}: {1}", (PSConstants)key, action.GetDouble(key));
                        break;
                    case PsDescValueType.psUnitDoubleType:
                        Debug.WriteLine("{0}: {1} {2}", (PSConstants)key, action.GetUnitDoubleValue(key), (PSConstants)action.GetUnitDoubleType(key));
                        break;
                    case PsDescValueType.psEnumeratedType:
                        Debug.WriteLine("{0}: {1} {2}", (PSConstants)key, (PSConstants)action.GetEnumerationType(key), (PSConstants)action.GetEnumerationValue(key));
                        break;
                    case PsDescValueType.psObjectType:
                        Debug.WriteLine($"{(PSConstants)key}: {(PSConstants)action.GetObjectType(key)} ");
                        Debug.Indent();
                        ActionPrinter(action.GetObjectValue(key));
                        Debug.Unindent();
                        break;
                    case PsDescValueType.psListType:
                        var list = action.GetList(key);
                        Debug.WriteLine($"{(PSConstants)key}: List of {list.Count} Items");
                        Debug.Indent();
                        for (int count = 0; count < list.Count; count++)
                        {
                            var type = list.GetType(count);
                            Debug.WriteLine($"{count}: {type} ");
                            Debug.Indent();
                            switch (type)
                            {
                                case PsDescValueType.psObjectType:
                                    ActionPrinter(list.GetObjectValue(count));
                                    break;
                                case PsDescValueType.psReferenceType:
                                    var reference = list.GetReference(count);
                                    Debug.WriteLine("    Reference to a {0}", (PSConstants)reference.GetDesiredClass());
                                    break;
                                case PsDescValueType.psEnumeratedType:
                                    Debug.WriteLine("    {0} {1}", (PSConstants)list.GetEnumerationType(count), (PSConstants)list.GetEnumerationValue(count));
                                    break;
                                default:
                                    Debug.WriteLine($"UNHANDLED LIST TYPE {type}");
                                    break;
                            }
                            Debug.Unindent();
                        }
                        Debug.Unindent();
                        break;
                    default:
                        Debug.WriteLine($"{(PSConstants)key} UNHANDLED TYPE {action.GetType(key)}");
                        break;
                }
            }
        }
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top