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
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
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
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
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.
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!
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); }
}
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
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); }
}
Copy link to clipboard
Copied
Thanks r-bin, you are truly awesome!