Copy link to clipboard
Copied
Hi everyone!
I tried to do what I need through actions and I couldn't. Is there any way to do it via script?
I need to select a layer mask, edit it, and then go to the next one, edit it, and so on. But finding them all and selecting them manually is time consuming. Is there a way to make this selection via script to move on to the next mask? Then it would be easier to add a shortcut to the script or create a new action with a function key.
Thanks!
1 Correct answer
const reverseOrder = false; // true - layers pass from top to bottom, false - from bottom to top
var s2t = stringIDToTypeID,
layerMasks = [];
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('hasBackgroundLayer'));
r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
var offset = executeActionGet(r).getBoolean(p) ? 1 : 0;
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('numberOfLayers'));
r.putEnumerated(s2t('document'), s2t('ordinal'), s2t
...
Explore related tutorials & articles
Copy link to clipboard
Copied
See if this helps. I built the action in the picture below, in only two steps. To record the Select Backward Layer step, I used the Option-[ shortcut (Alt-[ in Windows) which steps one layer back (down) in the stack. To record the Select Mask Channel step, I clicked the mask of the current layer.
You have to record the first step using the keyboard shortcut, not by clicking a layer. The reason is that if you click a layer, the action will record selecting a layer of a specific name, so that won’t work with any other layers. The keyboard shortcut is relative (next layer back regardless of the name), so it works with any layer stack.
That action displays an error if it hits a layer with no mask, like the Background, but you can press the Enter key to continue. You will probably also want to make an action going the other way, for the shortcut that steps to the next layer forward (up) in the stack using the Option/Alt-] shortcut, and selects its mask. Then you could reverse out of hitting the top or bottom of the stack.
You probably know this already, but after recordong an action, you can assign a function key to it by double-clicking the action (the shortcut for choosing Action Options from the Actions panel menu).
Copy link to clipboard
Copied
Thanks for the answer @Conrad_C!
Not all layers have masks. Using the backward layer or forward layer commands in the action, the selection will go through all layers, including those without masks. I need to select only the layers that have masks, one by one, to edit the masks.
Copy link to clipboard
Copied
Yeah, to do that then maybe a script is required. Although the Layers panel has filters, I don’t see one that will show only layers with masks, so maybe that can’t be done in an action.
Looks like jazz-y has just posted a script idea, you should probably move on to that (my scripting expertise basically doesn’t exist 🙂 )
Copy link to clipboard
Copied
const reverseOrder = false; // true - layers pass from top to bottom, false - from bottom to top
var s2t = stringIDToTypeID,
layerMasks = [];
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('hasBackgroundLayer'));
r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
var offset = executeActionGet(r).getBoolean(p) ? 1 : 0;
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('numberOfLayers'));
r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
var to = executeActionGet(r).getInteger(p);
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('itemIndex'));
r.putEnumerated(s2t('layer'), s2t('ordinal'), s2t('targetEnum'));
var activeLayer = executeActionGet(r).getInteger(p) - offset;
for (var i = 1; i <= to; i++) {
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('layerKind'));
r.putIndex(s2t('layer'), i);
if (executeActionGet(r).getInteger(p) != 13) {
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('hasUserMask'));
r.putIndex(s2t('layer'), i);
if (executeActionGet(r).getBoolean(p)) layerMasks.push(i)
}
}
if (reverseOrder) layerMasks.reverse()
var i = 0;
if (layerMasks.length) {
do {
if (i == layerMasks.length) { i = 0; activeLayer = reverseOrder ? to + 1 : 0 }
if (reverseOrder ? layerMasks[i] < activeLayer : layerMasks[i] > activeLayer) { activeLayer = layerMasks[i]; break; }
i++
} while (true)
(r = new ActionReference()).putIndex(s2t("layer"), activeLayer);
(d = new ActionDescriptor()).putReference(s2t("target"), r)
executeAction(s2t("select"), d, DialogModes.NO);
(r = new ActionReference()).putEnumerated(s2t("channel"), s2t('channel'), s2t('mask'));
(d = new ActionDescriptor()).putReference(s2t('target'), r);
executeAction(s2t('select'), d, DialogModes.NO);
}
Copy link to clipboard
Copied
Thanks @jazz-y. Worked Perfectly!

