Skip to main content
Participating Frequently
March 1, 2018
Respondido

Photoshop Scripting - Update Layers

  • March 1, 2018
  • 1 resposta
  • 1934 Visualizações

Hi there,

I am writing my first few Photoshop scripts and cannot figure out what would seem trivial tasks to do manually.

Firstly, how do you copy smart filters from sourceLayerRef to destLayerRef?

Secondly, is there a way to update a layer's pixels in place, preserving all other properties like, blend mode, opacity, layer effects, layer masks etc? I was hoping for something like destLayerRef.channels = sourceLayerRef.channels (or .rgb, .pixels, . contents?) but can only see copy & paste which is error prone when a layer mask is present.

Finally, how do you reference a sourceLayerRef's mask (raster)?

As an aside, I am familiar with scripting (javascript, php & maxscript) for other applications but have found the methods exposed to extendscript tend to be rather limited and getting complex tasks done often relies on the use of the ScriptListener plugin to create strange non-human readable actions. Does anyone else think that or am I going about my scripts in the wrong way?

Hope someone can get me on the right track!

Cheers,
Olly

Este tópico foi fechado para respostas.
Melhor resposta por r-bin

Thank you r-bin you are a legend - these are a really big help!

Is there a way to test if a layer has smart filters before attempting to copy them to the destLayerRef?

Thanks again,

Olly


OK. You can use the following functions.

///////////////////////////////////////////////////////// 

function get_filter_fx_count(layer_id) 

    { 

    try 

        { 

        var r = new ActionReference(); 

        r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("smartObject"));     

        r.putIdentifier(stringIDToTypeID("layer"), layer_id); 

 

        var d = executeActionGet(r); 

 

        if (!d.hasKey(stringIDToTypeID("smartObject"))) return 0; 

        d = d.getObjectValue(stringIDToTypeID("smartObject"));

        if (!d.hasKey(stringIDToTypeID("filterFX"))) return 0; 

        return d.getList(stringIDToTypeID("filterFX")).count; 

        } 

    catch (e) { throw(e); } 

    } 

///////////////////////////////////////////////////////// 

function del_filter_fx(layer_id) 

    { 

    try 

        { 

        if (!get_filter_fx_count(layer_id)) return;

        var r = new ActionReference(); 

        r.putClass( stringIDToTypeID("filterFX" ));

        r.putIdentifier(stringIDToTypeID("layer"), layer_id); 

        var d = new ActionDescriptor();

        d.putReference(stringIDToTypeID("target"), r); 

        executeAction(stringIDToTypeID("delete"), d, DialogModes.NO); 

        } 

    catch (e) { throw(e); } 

    } 

1 Resposta

Legend
March 1, 2018

On the first question I can offer

dup_layer_fx(sourceLayerRef.id, destLayerRef.id); // in CS6 does not work (id is undefined)

function dup_layer_fx(src_id, dst_id)

    {

    try

        {

        var d = new ActionDescriptor();

        var r = new ActionReference();

        r.putClass(stringIDToTypeID("filterFX"));

        r.putIdentifier(stringIDToTypeID("layer"), src_id);

        d.putReference(stringIDToTypeID("target"), r );

        var r = new ActionReference();

        r.putIdentifier(stringIDToTypeID("layer"), dst_id );

        d.putReference(stringIDToTypeID("to"), r);

        executeAction(stringIDToTypeID("duplicate"), d, DialogModes.NO );

        }

    catch (e) { alert(e) }

    }

For the rest I do not understand what you meant.

Reformulate the questions.

Participating Frequently
March 1, 2018

Thank you r-bin - I will try that.

To try again for question 2 & 3: I am trying to update layers (LayerKind.NORMAL) in a PSD with layers from a render file with the same name. I thought the easiest way to achieve this would be to update the content (pixels) of each layer so all other layer properties remain intact ie opacity, layer mask, blend mode. Maybe it is easier to copy the properties of the old layer to the new layer instead.

I also would like to know how to address a layer's mask so I can copy it from one layer to another, something like oldLayerRef.mask = newLayerRef.mask maybe? If not how do make a layer's mask active so you can paste into it from the clipboard?

All suggestions welcome!

r-binResposta
Legend
March 2, 2018

Thank you r-bin you are a legend - these are a really big help!

Is there a way to test if a layer has smart filters before attempting to copy them to the destLayerRef?

Thanks again,

Olly


OK. You can use the following functions.

///////////////////////////////////////////////////////// 

function get_filter_fx_count(layer_id) 

    { 

    try 

        { 

        var r = new ActionReference(); 

        r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("smartObject"));     

        r.putIdentifier(stringIDToTypeID("layer"), layer_id); 

 

        var d = executeActionGet(r); 

 

        if (!d.hasKey(stringIDToTypeID("smartObject"))) return 0; 

        d = d.getObjectValue(stringIDToTypeID("smartObject"));

        if (!d.hasKey(stringIDToTypeID("filterFX"))) return 0; 

        return d.getList(stringIDToTypeID("filterFX")).count; 

        } 

    catch (e) { throw(e); } 

    } 

///////////////////////////////////////////////////////// 

function del_filter_fx(layer_id) 

    { 

    try 

        { 

        if (!get_filter_fx_count(layer_id)) return;

        var r = new ActionReference(); 

        r.putClass( stringIDToTypeID("filterFX" ));

        r.putIdentifier(stringIDToTypeID("layer"), layer_id); 

        var d = new ActionDescriptor();

        d.putReference(stringIDToTypeID("target"), r); 

        executeAction(stringIDToTypeID("delete"), d, DialogModes.NO); 

        } 

    catch (e) { throw(e); } 

    }