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

Cycle through layer masks

Explorer ,
Mar 29, 2023 Mar 29, 2023

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!

TOPICS
Actions and scripting

Views

401

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 1 Correct answer

Guide , Mar 29, 2023 Mar 29, 2023

 

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
...

Votes

Translate

Translate
Community Expert ,
Mar 29, 2023 Mar 29, 2023

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.

Select-next-layer-mask-channel.jpg

 

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).

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
Explorer ,
Mar 29, 2023 Mar 29, 2023

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.

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 Expert ,
Mar 29, 2023 Mar 29, 2023

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 🙂 )

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
Guide ,
Mar 29, 2023 Mar 29, 2023

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

 

 

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
Explorer ,
Mar 29, 2023 Mar 29, 2023

Copy link to clipboard

Copied

LATEST

Thanks @jazz-y. Worked Perfectly!

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