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

How to center 2 layer masks at selection in photoshop

Explorer ,
May 10, 2022 May 10, 2022

When i try to center two images that are smart objects with layer masks with the align buttons in photoshop it alignes it according to the whole image and not only my selection. How can i center only my selection to an other mask and not the whole images?

TOPICS
macOS , Windows
4.9K
Translate
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
Adobe
Community Expert ,
Apr 06, 2025 Apr 06, 2025
quote

Just want to say thank you @Stephen Marsh! I've created a ton of work arounds for this very issue...wish I knew a simple solution was just a good search away.

I did notice that if you're trying to center a group that's masked it stops working as intended. Any idea on how to extend it to work with groups?

-Matt


By @Little_Matty

 

I have updated the previous scriptUI version to 1.1, however, I have not yet looked at aligning groups.

You could try converting each group to a smart object, aligning, and then converting the smart object back to a layer.

Translate
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 ,
May 25, 2022 May 25, 2022

Vote to add an option to align using mask bounds instead of layer bounds here:

 

https://community.adobe.com/t5/photoshop-ecosystem-ideas/photoshop-align-layers-using-the-masked-are...

 

Translate
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 ,
Apr 07, 2025 Apr 07, 2025

This 1.2 version should work correctly to align masked layer groups to the canvas.

Align_Masked_Layers_to_Canvas_1-2.png

/* 
Align Masked Layers to Canvas Using Mask Bounds ScriptUI v1-2.jsx
Stephen Marsh
v1.0 - 24th May 2022:  Initial release using a Radio Button UI
v1.1 - 7th April 2025: Revised to use Dropdown Menus
v1.2 - 7th April 2025: Revised to process layer groups (requires Photoshop 21.0)
https://community.adobe.com/t5/photoshop-ecosystem-discussions/how-to-center-2-layer-masks-at-selection-in-photoshop/td-p/12934857

Features: * Unlike the standard align feature, this script works correctly with layer masked content
          * Works with selected standard, smart object or layer groups containing layer masks
          * Single history step undo
*/

#target photoshop;

// Ensure that version 2021 or later is being used
var versionNumber = app.version.split(".");
var versionCheck = parseInt(versionNumber);
if (versionCheck < 22) {
    alert("You must use Photoshop 2021 or later to run this v1.2 script!");
} else {
    function main() {
        (function () {
            var savedRuler = app.preferences.rulerUnits;
            app.preferences.rulerUnits = Units.PIXELS;

            var userInput = showDialog();
            if (userInput === null) {
                app.preferences.rulerUnits = savedRuler;
                return;
            }

            if (/^(No Change|Left|Center|Right),(No Change|Top|Center|Bottom)$/.test(userInput)) {
                // Align the selected layers
                processSelectedLayers(userInput);
            }

            app.preferences.rulerUnits = savedRuler;

            function showDialog() {
                // Create the dialog window
                var dlg = new Window("dialog", "Align Masked Layers to Canvas (v1.2)");
                dlg.orientation = "column";
                dlg.alignChildren = "left";
                dlg.preferredSize.width = 300;

                // Add the panel for the dropdowns
                var dropdownGroup = dlg.add("panel", undefined, "Alignment Options");
                dropdownGroup.orientation = "column";
                dropdownGroup.alignChildren = "fill";
                dropdownGroup.margins = [10, 15, 10, 10];
                dropdownGroup.alignment = "fill";

                dropdownGroup.add("statictext", undefined, "X Alignment:");
                var xDropdown = dropdownGroup.add("dropdownlist", undefined, ["No Change", "Left", "Center", "Right"]);
                xDropdown.selection = 0;

                dropdownGroup.add("statictext", undefined, "Y Alignment:");
                var yDropdown = dropdownGroup.add("dropdownlist", undefined, ["No Change", "Top", "Center", "Bottom"]);
                yDropdown.selection = 0;

                var btnGroup = dlg.add("group");
                btnGroup.orientation = "row";
                btnGroup.alignment = "right";
                var cancel = btnGroup.add("button", undefined, "Cancel");
                var ok = btnGroup.add("button", undefined, "OK", { name: "ok" });
                ok.preferredSize.width = 80;
                cancel.preferredSize.width = 80;

                // Button event handlers
                var result = null;
                ok.onClick = function () {
                    result = xDropdown.selection.text + "," + yDropdown.selection.text;
                    dlg.close();
                };
                cancel.onClick = function () {
                    result = null;
                    dlg.close();
                };

                dlg.show();
                return result;
            }

            function processSelectedLayers(alignmentString) {
                var s2t = stringIDToTypeID;
                // Get the IDs of the currently selected layers
                var ref = new ActionReference();
                ref.putProperty(s2t("property"), s2t("targetLayersIDs"));
                ref.putEnumerated(s2t("document"), s2t("ordinal"), s2t("targetEnum"));
                var layerList = executeActionGet(ref).getList(s2t("targetLayersIDs"));
                var selectedIDs = [];
                for (var i = 0; i < layerList.count; i++) {
                    selectedIDs.push(layerList.getReference(i).getIdentifier(s2t("layerID")));
                }

                var tempSmartObjects = []; // Store [originalLayerID, newSmartObjectID]
                var finalLayerIDs = selectedIDs.slice(); // Ensure this is an array copy

                // Select the layers and align them
                for (var j = 0; j < selectedIDs.length; j++) {
                    selectLayerByID(selectedIDs[j]);
                    if (isLayerGroup()) {
                        executeAction(s2t("newPlacedLayer"), undefined, DialogModes.NO);
                        var newID = getActiveLayerID();
                        tempSmartObjects.push([selectedIDs[j], newID]);
                    }
                    alignByMask(alignmentString);
                }

                // Convert temporary smart objects back to layers and update final IDs
                // Requires Photoshop 21.0 or later
                for (var i = 0; i < tempSmartObjects.length; i++) {
                    selectLayerByID(tempSmartObjects[i][1]);
                    executeAction(s2t("placedLayerConvertToLayers"), undefined, DialogModes.NO);
                    var newLayerID = getActiveLayerID();
                    // Safely update finalLayerIDs
                    var originalID = tempSmartObjects[i][0];
                    var originalIndex = -1;
                    for (var k = 0; k < finalLayerIDs.length; k++) {
                        if (finalLayerIDs[k] === originalID) {
                            originalIndex = k;
                            break;
                        }
                    }
                    if (originalIndex !== -1) {
                        finalLayerIDs[originalIndex] = newLayerID;
                    } else {
                        // If not found, append the new ID (shouldn't happen, but as a fallback)
                        finalLayerIDs.push(newLayerID);
                    }
                }

                // Re-select the original layers
                if (finalLayerIDs.length > 0) {
                    // Deselect all layers first
                    var deselectDesc = new ActionDescriptor();
                    var deselectRef = new ActionReference();
                    deselectRef.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("allEnum"));
                    deselectDesc.putReference(s2t("target"), deselectRef);
                    executeAction(s2t("selectNoLayers"), deselectDesc, DialogModes.NO);
                    // Select all layers in finalLayerIDs
                    for (var k = 0; k < finalLayerIDs.length; k++) {
                        var selDesc = new ActionDescriptor();
                        var selRef = new ActionReference();
                        selRef.putIdentifier(s2t("layer"), finalLayerIDs[k]);
                        selDesc.putReference(s2t("target"), selRef);
                        if (k > 0) {
                            selDesc.putEnumerated(s2t("selectionModifier"), s2t("selectionModifierType"), s2t("addToSelection"));
                        }
                        selDesc.putBoolean(s2t("makeVisible"), false);
                        executeAction(s2t("select"), selDesc, DialogModes.NO);
                    }
                }
            }

            function isLayerGroup() {
                var ref = new ActionReference();
                ref.putProperty(stringIDToTypeID("property"), stringIDToTypeID("layerSection"));
                ref.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
                var desc = executeActionGet(ref);
                var type = desc.getEnumerationValue(stringIDToTypeID("layerSection"));
                var typeString = typeIDToStringID(type);
                return typeString === "layerSectionStart";
            }

            function getActiveLayerID() {
                var ref = new ActionReference();
                ref.putProperty(stringIDToTypeID("property"), stringIDToTypeID("layerID"));
                ref.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
                return executeActionGet(ref).getInteger(stringIDToTypeID("layerID"));
            }

            function selectLayerByID(ID) {
                var ref = new ActionReference();
                ref.putIdentifier(stringIDToTypeID("layer"), ID);
                var desc = new ActionDescriptor();
                desc.putReference(stringIDToTypeID("target"), ref);
                desc.putBoolean(stringIDToTypeID("makeVisible"), false);
                executeAction(stringIDToTypeID("select"), desc, DialogModes.NO);
            }

            function alignByMask(userInput) {
                var parts = userInput.split(",");
                var xAlign = parts[0];
                var yAlign = parts[1];

                var canvasLeft = 0;
                var canvasTop = 0;
                var canvasRight = activeDocument.width.value;
                var canvasBottom = activeDocument.height.value;
                var canvasXCenter = activeDocument.width.value / 2;
                var canvasYCenter = activeDocument.height.value / 2;

                var bounds = activeDocument.activeLayer.bounds;
                var layerLeft = bounds[0].value;
                var layerTop = bounds[1].value;
                var layerRight = bounds[2].value;
                var layerBottom = bounds[3].value;
                var layerWidth = layerRight - layerLeft;
                var layerHeight = layerBottom - layerTop;

                var dx = 0;
                var dy = 0;

                switch (xAlign) {
                    case "Left": dx = canvasLeft - layerLeft; break;
                    case "Center": dx = canvasXCenter - layerLeft - layerWidth / 2; break;
                    case "Right": dx = canvasRight - layerRight; break;
                }

                switch (yAlign) {
                    case "Top": dy = canvasTop - layerTop; break;
                    case "Center": dy = canvasYCenter - layerTop - layerHeight / 2; break;
                    case "Bottom": dy = canvasBottom - layerBottom; break;
                }

                activeDocument.activeLayer.translate(dx, dy);
            }
        })();
    }
}
activeDocument.suspendHistory("Align Masked Layers to Canvas", "main()");

 

  1. Copy the code text to the clipboard
  2. Open a new blank file in a plain-text editor (not in a word processor)
  3. Paste the code in
  4. Save as a plain text format file – .txt
  5. Rename the saved file extension from .txt to .jsx
  6. Install or browse to the .jsx file to run (see below)

https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html

Translate
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 ,
Apr 07, 2025 Apr 07, 2025

Works like a charm. Thanks for revisiting this @Stephen Marsh !

Best.

Matt

Translate
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 ,
Apr 07, 2025 Apr 07, 2025
LATEST

@Little_Matty - You're welcome! I cheated using temporary smart objects. Time permitting I'll look into using the bounds of the mask.

Translate
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