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

Photoshop Scripting - Update Layers

Community Beginner ,
Mar 01, 2018 Mar 01, 2018

Copy link to clipboard

Copied

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

TOPICS
Actions and scripting

Views

1.3K

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
community guidelines

correct answers 3 Correct answers

People's Champ , Mar 01, 2018 Mar 01, 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

...

Votes

Translate

Translate
People's Champ , Mar 01, 2018 Mar 01, 2018

On the last question you can also use the code from Action Magager obtained with the ScriptListener plugin.

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

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

function dup_layer_mask(src_id, dst_id)

    {

    try

        {

        var d = new ActionDescriptor();

        d.putClass(stringIDToTypeID("new"), stringIDToTypeID("channel"));

        var r = new ActionReference();

        r.putEnumerated(st

...

Votes

Translate

Translate
People's Champ , Mar 02, 2018 Mar 02, 2018

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(s

...

Votes

Translate

Translate
Adobe
People's Champ ,
Mar 01, 2018 Mar 01, 2018

Copy link to clipboard

Copied

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.

Votes

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
community guidelines
Community Beginner ,
Mar 01, 2018 Mar 01, 2018

Copy link to clipboard

Copied

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!

Votes

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
community guidelines
People's Champ ,
Mar 01, 2018 Mar 01, 2018

Copy link to clipboard

Copied

On the last question you can also use the code from Action Magager obtained with the ScriptListener plugin.

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

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

function dup_layer_mask(src_id, dst_id)

    {

    try

        {

        var d = new ActionDescriptor();

        d.putClass(stringIDToTypeID("new"), stringIDToTypeID("channel"));

        var r = new ActionReference();

        r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("mask"));

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

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

        d.putBoolean(stringIDToTypeID("duplicate"), true );

        var r = new ActionReference();

        r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("mask"));

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

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

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

        }

    catch (e) { alert(e) }

    }

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

function has_layer_mask(layer_id)

    {

    try

        {

        var r = new ActionReference();

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

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

        var d = executeActionGet(r);

        if (!d.hasKey(stringIDToTypeID("hasUserMask"))) return false;

        return d.getBoolean(stringIDToTypeID("hasUserMask"));

        }

    catch (e) { throw(e); }

    }

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

function del_layer_mask(layer_id, apply)

    {

    try {

        if (!has_layer_mask(layer_id)) return;

        select_layer_mask(layer_id);

        var r = new ActionReference();

        r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("mask"));

        var d = new ActionDescriptor();

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

        if (apply) d.putBoolean(stringIDToTypeID("apply"), true);

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

        }

    catch (e) { throw(e); }

    }  

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

function select_layer_mask(layer_id)

    {

    try {

        var r = new ActionReference();

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

        var d = new ActionDescriptor();

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

        d.putBoolean(stringIDToTypeID("makeVisible"), false);

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

        var r = new ActionReference();

        r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("mask"));

        var d = new ActionDescriptor();

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

        d.putBoolean(stringIDToTypeID("makeVisible"), false);

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

        }

    catch (e) { throw(e); }

    }

In the matter of updating the layer. Unclear. How are you going to update the pixels?

If this is a smart object, then updating (replacing) the content does not affect the masks and blending modes. If this is a new layer, then you need to copy the mask and effects.

The function copies fx to the clipboard if the layer has effects or a non-standard mode, even the opacity != 100

If returns 'true' you can use fx_paste()

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

function fx_copy()

    {      

    try { executeAction( stringIDToTypeID("copyEffects"), undefined, DialogModes.NO ); } catch (e) { return false; }

    return true;

    }

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

function fx_paste()

    {      

    try {

        var d = new ActionDescriptor();

        d.putBoolean(stringIDToTypeID( "allowPasteFXOnLayerSet" ), true);

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

        }

    catch (e) { throw(e); }

    }

Votes

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
community guidelines
Community Beginner ,
Mar 02, 2018 Mar 02, 2018

Copy link to clipboard

Copied

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

Votes

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
community guidelines
People's Champ ,
Mar 02, 2018 Mar 02, 2018

Copy link to clipboard

Copied

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); } 

    } 

Votes

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
community guidelines
Community Beginner ,
Mar 02, 2018 Mar 02, 2018

Copy link to clipboard

Copied

LATEST

Thanks r-bin, you are truly awesome!

Votes

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
community guidelines