Copy link to clipboard
Copied
Hello community, hope eveybody is doing great!
I would need your help on expanding a script set that relies on mask properties.
My current workflow consists of stacking some layers into a single file and then auto creating masks,
based on their content attributes.
Since the task is based on a same repeated object set, the results of the masks produced,
can be classified into 5 "categories" depending on the size of the object detected or not.
For the sake of simplicity I name them after :
1) White Mask
2) Black Mask
3) Large Mask
4) Medium Mask
5) Small Mask
For each result I have assigned a script that performs certain actions.
1 & 5 ) Perfom no action in mask is White or Black
2) Perform ("Subtrack 25px", "Large Masks")
3) Perform ("Subtrack 5px", "Medium Masks")
4) Perform ("Expand 25px", "Small Masks")
The latter processes are performed manually via a quick visual selection and the used
of a modded PS-Scripts-master subset like "Run [X] Action on selected layers"
I was wondering if there is any method to iterate / "measure" each mask content,
and based on a specific value ( like Mean Histogram Value with of Selected Layer while mask is visible )
conditionally perform the above actions based on a certain range.
Example Mean Range Values :
1) O < No action < 200
2) 200 < Subtract 25px < 220
3) 221 < Subtract 5px < 235
4) 236 < Expand 25px < 249
5) 249 < Expand 25px < 255
To the moment I havent found a way to access these values in direct.
The only thing I have come up with - but havent tried yet - is to temporarily,
make each single layer visible, create a temporary pixel layer on top of from the mask,
measure it, play the action on the "parent" below and delete the temp layer.
Any help would be much appreciated !
1 Correct answer
That script was to serve as an example of how to get the mean from a Histogram, not a solution for the whole process.
The Histogram of a Layer Mask can be assessed.
// 2023, use it at your own risk;
if (app.documents.length > 0) {
if (hasLayerMask() == true) {
selectLayerMask();
var ref = new ActionReference();
ref.putProperty (stringIDToTypeID ("property"), stringIDToTypeID ("histogram"));
ref.putEnumerated( charIDToTypeID("Chnl"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var docDes
...
Explore related tutorials & articles
Copy link to clipboard
Copied
Please provide a sample file to clarify what you mean.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Hi @c.pfaffenbichler and thanks for your time ! I have had a quick look already at that but the script returns the luminosity values of the composite image itself, not the ones that derive from the mask. When running the script having the mask selected the return is
Error 8500: The requested property does not exist. so I guess the property that I am asking for is not retrievable. Even so, and if I proceed by temp. converting masks into layers, is there any scripting reference on these conditionals?
Copy link to clipboard
Copied
That script was to serve as an example of how to get the mean from a Histogram, not a solution for the whole process.
The Histogram of a Layer Mask can be assessed.
// 2023, use it at your own risk;
if (app.documents.length > 0) {
if (hasLayerMask() == true) {
selectLayerMask();
var ref = new ActionReference();
ref.putProperty (stringIDToTypeID ("property"), stringIDToTypeID ("histogram"));
ref.putEnumerated( charIDToTypeID("Chnl"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var docDesc = executeActionGet(ref);
var list = docDesc.getList(stringIDToTypeID("histogram"));
var theArray = new Array;
var theHist0 = list.getInteger(0);
for (var i = 0; i < list.count; i++) {
var d = list.getInteger(i);
theArray.push(d);
};
alert(theArray.length+"\n"+theArray.join("\n"));
};
};
////////////////////////////////////
////// has layer mask //////
function hasLayerMask () {
var m_Dsc01, m_Ref01;
m_Ref01 = new ActionReference();
m_Ref01.putEnumerated(stringIDToTypeID("layer"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
m_Dsc01 = executeActionGet(m_Ref01);
return m_Dsc01.hasKey(charIDToTypeID("Usrs"));
};
////// select layer mask //////
function selectLayerMask () {
var desc4 = new ActionDescriptor();
var ref1 = new ActionReference();
ref1.putEnumerated( stringIDToTypeID( "channel" ), stringIDToTypeID( "channel" ), stringIDToTypeID( "mask" ) );
//ref1.putIdentifier(charIDToTypeID('Lyr '), theId);
desc4.putReference( stringIDToTypeID( "null" ), ref1 );
desc4.putBoolean( stringIDToTypeID( "makeVisible" ), false );
executeAction( stringIDToTypeID( "select" ), desc4, DialogModes.NO );
};
Copy link to clipboard
Copied
That was it !!! Big thanks @c.pfaffenbichler and @Stephen Marsh also for your precious time !
Copy link to clipboard
Copied
Update : Sample PSD containing example cases. Layer names are arbitrary and only renamed for example purposes.
Copy link to clipboard
Copied
Another option could be to load the channel as a selection and get the selection bounds info. You could then set up conditionals based on the width, height or area etc. of the selection.
Copy link to clipboard
Copied
How do you "auto-create masks" and could you do something at that step (add a keyword or note) that would indicate further processing?
Copy link to clipboard
Copied
The masks are created in a 2.5 steps process. I create white masks for each layer and then I process with 2 loops of a certain action. One is responsible for recognizing a certain color range and passing the color range findings with selection=>"black color fill" and the other pass is targeting and adding a second color range if any. The resulting mask is a simple combo of the above findings. Since the process is applied to a very certain and always repeated pattern, the mask size aids me to recognize and pre empitively correct any deviations instead of manually checking each layer one by one.
Copy link to clipboard
Copied
The idea of keywording/annotating is right at the core of my thoughts, yet I havent found a way to implement it correctly, in a way that fits my needs.

