Skip to main content
Participating Frequently
February 2, 2025
Answered

PS Scripting: Copy + Paste Layer Mask Content from one to another?

  • February 2, 2025
  • 3 replies
  • 2327 views

Hi!

I'm currently working on some automation in our workflow and updating Adjustment layers would be a big point on that list. We're editing our renderings with a bunch of pre-defined adjustment layers, where we can edit them manually. But if the rendering gets an update, we have to copy+paste all the values from the old file into the new file (with the new render output). For now I'm duplicating all the adjustment layers from the old file into the new one and then I update every single layer mask with some copy+paste frenzy.  

While I already did improve some parts of the workflow with some basic JavaScript ... very basic, very trashy, but it gets the work done ... I'm really struggling with that part. It seems like getting / setting the values of each adjustment layer (talking about Curves, HueSat, Exposure, LUT, ...) is nearly impossible. Setting the values can be done with the stuff the Scripting Listeners spits out, but I realy have no clue how I would get the values in the same 'easy' way as the listener prints out. And even imitating the workflow I'm using right now - copy+pasting the new layer mask onto the old adjustment layers - isn't working. Same thing here: Scripting LIstener gives me some output, but I can't re-use anything of it? 

 

Creating an Action could work, if the hierarchy is identical between the old and new file. But quite often there are some additional adjustment layers on top of all the default ones. And these layers would sabotage the PS Action I guess ... 

 

Is this idea for a script really a little big or am I missing something? Maybe someone already did something similar? 🙂 

 

Thanks anyway and have a nice day!

Correct answer Stephen Marsh

@David3065392143nx 

 

You can try the following v1.0 script. 

 

I have updated the script to v1.1...  I'm happy to make adjustments based on your feedback.

 

The first document opened must be the original render. The second document opened must be the new render. 

 

/*
Update Render Adjustment Layers.jsx
Stephen Marsh
v1.1 - 3rd February 2025
https://community.adobe.com/t5/photoshop-ecosystem-discussions/ps-scripting-copy-paste-layer-mask-content-from-one-to-another/td-p/15127773
Note: The original document should be the first render opened, the second should be the new render
*/

#target photoshop

if (app.documents.length == 2) {
    app.activeDocument.suspendHistory("Update Render Adjustment Layers", "main()");
} else {
    alert("There should only be two documents open!\rThe original document should be the first render opened, the second should be the new render.");
}

function main() {

    var origDoc = app.documents[0];
    var origDocName = origDoc.name;
    var newDoc = app.documents[1];
    var newDocName = newDoc.name;

    // Set the original document as the active document
    app.activeDocument = origDoc;

    // Apply the mask from the new render document to the original document
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Trees_Curves"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Trees_HueSat"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bushes_Curves"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bushes_HueSat"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Street_Curves"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Street_ColFill"];
    selectLayerChannel("mask");
    applyImage("Street_ColFill", newDocName);

    // Delete the adjustment layers from the new render document
    app.activeDocument = newDoc;
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Trees_Curves"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Trees_HueSat"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Bushes_Curves"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Bushes_HueSat"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Street_Curves"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Street_ColFill"];
    newDoc.activeLayer.remove();

    // Duplicate the adjustment layers from the original document
    app.activeDocument = origDoc;
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Trees_Curves"];
    dupeLayer("Trees_Curves");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Trees_HueSat"];
    dupeLayer("Trees_HueSat");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bushes_Curves"];
    dupeLayer("Bushes_Curves");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bushes_HueSat"];
    dupeLayer("Bushes_HueSat");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Street_Curves"];
    dupeLayer("Street_Curves");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Street_ColFill"];
    dupeLayer("Street_ColFill");

    // Revert to previous state
    executeAction(stringIDToTypeID("revert"), undefined, DialogModes.NO);
    // Close the original doc
    origDoc.close(SaveOptions.DONOTSAVECHANGES);

    // Return to the new document
    app.activeDocument = newDoc;


    // Functions

    function applyImage() {
        var s2t = function (s) {
            return app.stringIDToTypeID(s);
        };
        var descriptor = new ActionDescriptor();
        var descriptor2 = new ActionDescriptor();
        var reference = new ActionReference();
        reference.putEnumerated(s2t("channel"), s2t("channel"), s2t("mask"));
        reference.putName(s2t("layer"), app.activeDocument.activeLayer.name); // Source layer name
        reference.putName(s2t("document"), newDocName); // Source doc name
        descriptor2.putReference(s2t("to"), reference);
        descriptor2.putBoolean(s2t("preserveTransparency"), true);
        descriptor.putObject(s2t("with"), s2t("calculation"), descriptor2);
        executeAction(s2t("applyImageEvent"), descriptor, DialogModes.NO);
    }

    function selectLayerChannel(chanPara) {
        // "RGB" | "mask"
        var s2t = function (s) {
            return app.stringIDToTypeID(s);
        };
        var descriptor = new ActionDescriptor();
        var reference = new ActionReference();
        reference.putEnumerated(s2t("channel"), s2t("channel"), s2t(chanPara));
        descriptor.putReference(s2t("null"), reference);
        descriptor.putBoolean(s2t("makeVisible"), false);
        executeAction(s2t("select"), descriptor, DialogModes.NO);
    }

    function dupeLayer(dupeLayerName) {
        var s2t = function (s) {
            return app.stringIDToTypeID(s);
        };
        var descriptor = new ActionDescriptor();
        var list = new ActionList();
        var reference = new ActionReference();
        var reference2 = new ActionReference();
        reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
        descriptor.putReference(s2t("null"), reference);
        reference2.putName(s2t("document"), newDocName);
        descriptor.putReference(s2t("to"), reference2);
        descriptor.putString(s2t("name"), dupeLayerName);
        executeAction(s2t("duplicate"), descriptor, DialogModes.NO);
    }
}

 

  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

 

3 replies

Stephen Marsh
Stephen MarshCorrect answer
Community Expert
February 3, 2025

@David3065392143nx 

 

You can try the following v1.0 script. 

 

I have updated the script to v1.1...  I'm happy to make adjustments based on your feedback.

 

The first document opened must be the original render. The second document opened must be the new render. 

 

/*
Update Render Adjustment Layers.jsx
Stephen Marsh
v1.1 - 3rd February 2025
https://community.adobe.com/t5/photoshop-ecosystem-discussions/ps-scripting-copy-paste-layer-mask-content-from-one-to-another/td-p/15127773
Note: The original document should be the first render opened, the second should be the new render
*/

#target photoshop

if (app.documents.length == 2) {
    app.activeDocument.suspendHistory("Update Render Adjustment Layers", "main()");
} else {
    alert("There should only be two documents open!\rThe original document should be the first render opened, the second should be the new render.");
}

function main() {

    var origDoc = app.documents[0];
    var origDocName = origDoc.name;
    var newDoc = app.documents[1];
    var newDocName = newDoc.name;

    // Set the original document as the active document
    app.activeDocument = origDoc;

    // Apply the mask from the new render document to the original document
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Trees_Curves"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Trees_HueSat"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bushes_Curves"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bushes_HueSat"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Street_Curves"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Street_ColFill"];
    selectLayerChannel("mask");
    applyImage("Street_ColFill", newDocName);

    // Delete the adjustment layers from the new render document
    app.activeDocument = newDoc;
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Trees_Curves"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Trees_HueSat"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Bushes_Curves"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Bushes_HueSat"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Street_Curves"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Street_ColFill"];
    newDoc.activeLayer.remove();

    // Duplicate the adjustment layers from the original document
    app.activeDocument = origDoc;
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Trees_Curves"];
    dupeLayer("Trees_Curves");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Trees_HueSat"];
    dupeLayer("Trees_HueSat");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bushes_Curves"];
    dupeLayer("Bushes_Curves");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bushes_HueSat"];
    dupeLayer("Bushes_HueSat");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Street_Curves"];
    dupeLayer("Street_Curves");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Street_ColFill"];
    dupeLayer("Street_ColFill");

    // Revert to previous state
    executeAction(stringIDToTypeID("revert"), undefined, DialogModes.NO);
    // Close the original doc
    origDoc.close(SaveOptions.DONOTSAVECHANGES);

    // Return to the new document
    app.activeDocument = newDoc;


    // Functions

    function applyImage() {
        var s2t = function (s) {
            return app.stringIDToTypeID(s);
        };
        var descriptor = new ActionDescriptor();
        var descriptor2 = new ActionDescriptor();
        var reference = new ActionReference();
        reference.putEnumerated(s2t("channel"), s2t("channel"), s2t("mask"));
        reference.putName(s2t("layer"), app.activeDocument.activeLayer.name); // Source layer name
        reference.putName(s2t("document"), newDocName); // Source doc name
        descriptor2.putReference(s2t("to"), reference);
        descriptor2.putBoolean(s2t("preserveTransparency"), true);
        descriptor.putObject(s2t("with"), s2t("calculation"), descriptor2);
        executeAction(s2t("applyImageEvent"), descriptor, DialogModes.NO);
    }

    function selectLayerChannel(chanPara) {
        // "RGB" | "mask"
        var s2t = function (s) {
            return app.stringIDToTypeID(s);
        };
        var descriptor = new ActionDescriptor();
        var reference = new ActionReference();
        reference.putEnumerated(s2t("channel"), s2t("channel"), s2t(chanPara));
        descriptor.putReference(s2t("null"), reference);
        descriptor.putBoolean(s2t("makeVisible"), false);
        executeAction(s2t("select"), descriptor, DialogModes.NO);
    }

    function dupeLayer(dupeLayerName) {
        var s2t = function (s) {
            return app.stringIDToTypeID(s);
        };
        var descriptor = new ActionDescriptor();
        var list = new ActionList();
        var reference = new ActionReference();
        var reference2 = new ActionReference();
        reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
        descriptor.putReference(s2t("null"), reference);
        reference2.putName(s2t("document"), newDocName);
        descriptor.putReference(s2t("to"), reference2);
        descriptor.putString(s2t("name"), dupeLayerName);
        executeAction(s2t("duplicate"), descriptor, DialogModes.NO);
    }
}

 

  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

 

Participating Frequently
February 3, 2025

Hi Stephen!

 

Thank you for that script. It worked perfectly fine! (even though, in line 9, the # comment of target photoshop didn't work on my side. I've changed it to // and thats it ... if anyone else maybe copies that code 🙂 )

 

For the test 'environment' everything worked out of the box. I've modified the script to our bigger files, containing many more adjustment layers. (many of them in german, thats why I've created some test layers :)) And I've commented the reverting+closing of the original document because there are some additional tasks that are worked on manually after that. 🙂 I'll paste the full script at the end. Feedback: Big thanks for that great little helper! Really wondering how anyone can wrap his head around that ActionDescriptor stuff. I really thought with using the Scripting Listener myself and watching tutorials this would make some sense soon, but nope. 🙂 

 

One thing that would be "missing" now is the part with the custom adjustment layers. All the 26 hard coded layers are the same everytime. But everything above would be per-file-based. Would you say that can be achieved quite easily? I've once iterated through all the layers inside a layer set, but I can't find any of those test scripts. Maybe an iteration through all the layers, until the top default layer ('Dachbegrünung LUT') is found, could work? Then, copying those layers to the new file and create a Clipping mask. (thats where the problems happend too, the last time ...) ... There is no need to copy an existing mask (based on naming or something), because these are most likely changed anyway.

 

And a question also: The one part with the Solid Color / Color Fill. There the code is different to all the other layers. Is this something that is needed for Solid Color layers? Or is it because its the last layer in the list?

 

Thanks again! Really helping out! 

 

The modified script with my changes:

 

/*
Update Render Adjustment Layers.jsx
Stephen Marsh
v1.1 - 3rd February 2025
https://community.adobe.com/t5/photoshop-ecosystem-discussions/ps-scripting-copy-paste-layer-mask-content-from-one-to-another/td-p/15127773
Note: The original document should be the first render opened, the second should be the new render
*/

//#target photoshop

if (app.documents.length == 2) {
    app.activeDocument.suspendHistory("Update Render Adjustment Layers", "main()");
} else {
    alert("There should only be two documents open!\rThe original document should be the first render opened, the second should be the new render.");
}

function main() {

    var origDoc = app.documents[0];
    var newDocName = origDoc.name;
    var newDoc = app.documents[1];
    var newDocName = newDoc.name;

    // Set the original document as the active document
    app.activeDocument = origDoc;

    // Apply the mask from the new render document to the original document
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Rasen Kurven"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Rasen Farbton Sättigung uniform"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Rasen Farbton/Sättigung"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Rasen_LUT"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Wiese Kurven"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Wiese_LUT"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Wiese Farbton/Sättigung"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bäume Kurve"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bäume_LUT"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bäume Farbton/Sättigung"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Hecke Kurve"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Hecke_LUT"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Hecken Farbton/Sättigung"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Büsche Kurve"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Büsche Farbton Sättigung"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Büsche_LUT"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Stauden Kurven"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Stauden_LUT"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Ranken Kurve"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Ranken_LUT"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Boardstein Kurven"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Strassen Kurven"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Color Fill Strasse"];
    selectLayerChannel("mask");
    applyImage("Color Fill Strasse", newDocName);
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Untersicht Kurve"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Dachbegrünung Kurven"];
    selectLayerChannel("mask");
    applyImage();
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Dachbegrünung LUT"];
    selectLayerChannel("mask");
    applyImage();

    // Delete the adjustment layers from the new render document
    app.activeDocument = newDoc;
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Rasen Kurven"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Rasen Farbton Sättigung uniform"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Rasen Farbton/Sättigung"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Rasen_LUT"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Wiese Kurven"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Wiese_LUT"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Wiese Farbton/Sättigung"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Bäume Kurve"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Bäume_LUT"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Bäume Farbton/Sättigung"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Hecke Kurve"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Hecke_LUT"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Hecken Farbton/Sättigung"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Büsche Kurve"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Büsche Farbton Sättigung"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Büsche_LUT"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Stauden Kurven"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Stauden_LUT"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Ranken Kurve"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Ranken_LUT"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Boardstein Kurven"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Strassen Kurven"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Color Fill Strasse"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Untersicht Kurve"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Dachbegrünung Kurven"];
    newDoc.activeLayer.remove();
    newDoc.activeLayer = newDoc.layerSets["Render"].layers["Dachbegrünung LUT"];
    newDoc.activeLayer.remove();

    // Duplicate the adjustment layers from the original document
    app.activeDocument = origDoc;
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Rasen Kurven"];
    dupeLayer("Rasen Kurven");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Rasen Farbton Sättigung uniform"];
    dupeLayer("Rasen Farbton Sättigung uniform");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Rasen Farbton/Sättigung"];
    dupeLayer("Rasen Farbton/Sättigung");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Rasen_LUT"];
    dupeLayer("Rasen_LUT");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Wiese Kurven"];
    dupeLayer("Wiese Kurven");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Wiese_LUT"];
    dupeLayer("Wiese_LUT");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Wiese Farbton/Sättigung"];
    dupeLayer("Wiese Farbton/Sättigung");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bäume Kurve"];
    dupeLayer("Bäume Kurve");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bäume_LUT"];
    dupeLayer("Bäume_LUT");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bäume Farbton/Sättigung"];
    dupeLayer("Bäume Farbton/Sättigung");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Hecke Kurve"];
    dupeLayer("Hecke Kurve");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Hecke_LUT"];
    dupeLayer("Hecke_LUT");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Hecken Farbton/Sättigung"];
    dupeLayer("Hecken Farbton/Sättigung");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Büsche Kurve"];
    dupeLayer("Büsche Kurve");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Büsche Farbton Sättigung"];
    dupeLayer("Büsche Farbton Sättigung");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Büsche_LUT"];
    dupeLayer("Büsche_LUT");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Stauden Kurven"];
    dupeLayer("Stauden Kurven");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Stauden_LUT"];
    dupeLayer("Stauden_LUT");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Ranken Kurve"];
    dupeLayer("Ranken Kurve");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Ranken_LUT"];
    dupeLayer("Ranken_LUT");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Boardstein Kurven"];
    dupeLayer("Boardstein Kurven");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Strassen Kurven"];
    dupeLayer("Strassen Kurven");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Color Fill Strasse"];
    dupeLayer("Color Fill Strasse");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Untersicht Kurve"];
    dupeLayer("Untersicht Kurve");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Dachbegrünung Kurven"];
    dupeLayer("Dachbegrünung Kurven");
    origDoc.activeLayer = origDoc.layerSets["Render"].layers["Dachbegrünung LUT"];
    dupeLayer("Dachbegrünung LUT");

    // Revert to previous state ... would be nice, but takes too much time with our .psb files (~ 5 seconds)
    //executeAction(stringIDToTypeID("revert"), undefined, DialogModes.NO);

    // Close the original doc ... not needed (for now), additional tasks follow
    //origDoc.close(SaveOptions.DONOTSAVECHANGES);

    // Return to the new document
    app.activeDocument = newDoc;


    // Functions

    function applyImage() {
        var s2t = function (s) {
            return app.stringIDToTypeID(s);
        };
        var descriptor = new ActionDescriptor();
        var descriptor2 = new ActionDescriptor();
        var reference = new ActionReference();
        reference.putEnumerated(s2t("channel"), s2t("channel"), s2t("mask"));
        reference.putName(s2t("layer"), app.activeDocument.activeLayer.name); // Source layer name
        reference.putName(s2t("document"), newDocName); // Source doc name
        descriptor2.putReference(s2t("to"), reference);
        descriptor2.putBoolean(s2t("preserveTransparency"), true);
        descriptor.putObject(s2t("with"), s2t("calculation"), descriptor2);
        executeAction(s2t("applyImageEvent"), descriptor, DialogModes.NO);
    }

    function selectLayerChannel(chanPara) {
        // "RGB" | "mask"
        var s2t = function (s) {
            return app.stringIDToTypeID(s);
        };
        var descriptor = new ActionDescriptor();
        var reference = new ActionReference();
        reference.putEnumerated(s2t("channel"), s2t("channel"), s2t(chanPara));
        descriptor.putReference(s2t("null"), reference);
        descriptor.putBoolean(s2t("makeVisible"), false);
        executeAction(s2t("select"), descriptor, DialogModes.NO);
    }

    function dupeLayer(dupeLayerName) {
        var s2t = function (s) {
            return app.stringIDToTypeID(s);
        };
        var descriptor = new ActionDescriptor();
        var list = new ActionList();
        var reference = new ActionReference();
        var reference2 = new ActionReference();
        reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
        descriptor.putReference(s2t("null"), reference);
        reference2.putName(s2t("document"), newDocName);
        descriptor.putReference(s2t("to"), reference2);
        descriptor.putString(s2t("name"), dupeLayerName);
        executeAction(s2t("duplicate"), descriptor, DialogModes.NO);
    }
}

 

 

 

Stephen Marsh
Community Expert
February 5, 2025

I'm afraid that I'm not that  far with understanding that stuff?

 

var origDoc = app.documents[0];
var origDocName = origDoc.name;
var newDoc = app.documents[1];
var newDocName = newDoc.name;

app.activeDocument = origDoc;
app.activeDocument.activeLayer = app.activeDocument.layerSets["Render"];
selectLayerChannel("mask");

app.activeDocument = newDoc;
app.activeDocument.activeLayer = app.activeDocument.layerSets["Render"];
selectLayerChannel("mask");
alert (origDoc.activeLayer.name)

// Trying to target the origDoc Render LayerSet Mask; to apply the mask image to the currently + correctly selected Render 
// =======================================================
var idAppI = charIDToTypeID( "AppI" );
    var desc531 = new ActionDescriptor();
    var idWith = charIDToTypeID( "With" );
        var desc532 = new ActionDescriptor();
        var idT = charIDToTypeID( "T   " );
            var ref51 = new ActionReference();
            var idChnl = charIDToTypeID( "Chnl" );
            var idOrdn = charIDToTypeID( "Ordn" );
            var idTrgt = charIDToTypeID( "Trgt" );
            ref51.putEnumerated( idChnl, idOrdn, idTrgt );
            var idLyr = charIDToTypeID( "Lyr " );
            ref51.putName( idLyr, origDoc.activeLayer.name );
            var idDcmn = charIDToTypeID( "Dcmn" );
            ref51.putName( idDcmn, origDoc.name );
        desc532.putReference( idT, ref51 );
        var idPrsT = charIDToTypeID( "PrsT" );
        desc532.putBoolean( idPrsT, true );
    var idClcl = charIDToTypeID( "Clcl" );
    desc531.putObject( idWith, idClcl, desc532 );
executeAction( idAppI, desc531, DialogModes.NO );



function selectLayerChannel(chanPara) {
    // "RGB" | "mask"
    var s2t = function (s) {
        return app.stringIDToTypeID(s);
    };
    var descriptor = new ActionDescriptor();
    var reference = new ActionReference();
    reference.putEnumerated(s2t("channel"), s2t("channel"), s2t(chanPara));
    descriptor.putReference(s2t("null"), reference);
    descriptor.putBoolean(s2t("makeVisible"), false);
    executeAction(s2t("select"), descriptor, DialogModes.NO);
}

 

I've created a new script that only tries to get the Original Render (Layer Group) Layer Mask Image to the  New Render (Layer Group) Layer mask. While selecting both masks in both documents works fine with your scripts, I can't get the Apply Image method working - at least not, that it selects the Layer Group Render. If there is another layer inside that is called Render, it always copies the wrong one. Even when I try to address the layer via activeLayer. (ofc, the name is Render too .. so that won't help)

 

ref51.putName( idLyr, origDoc.layerSets["Render"] );

Also changing the ref to the target layer gives me no working code. (Seems like that doesn't work?) I assume it could be connected to the  part where idLyr is defined? (var idLyr = charIDToTypeID( "Lyr " );) ... 

Also tried to call the Apply Image function twice to see, if the second time it gets the next Render, but nope. I know learning works best with finding the solution on my own, but I guess I'm stuck again. Sorry 😄

 


@David3065392143nx 

 

From my tests, I believe that this is a bug/limitation of AM code and/or SL when there are both one or more layer groups and layers with the same name. It appears that the code applies the layer rather than the mask. This doesn't happen when using the interface to perform the task manually. So another good reason to use unique names!

 

I didn't know that you would apply the mask from one group to another.

 

So, there are two ways around this that I can see:

 

1) The script can rename the Render layer group or all groups so that they are unique and don't clash with the layers ("Render Group" or "Render 1" etc) and then the apply image code will work as expected.

 

2) Script the copy and paste of the group mask from one doc to the other.

 

P.S. I have corrected the original code as there was a minor error in the global variables for the docs/names:

 

var origDoc = app.documents[0];
var origDocName = origDoc.name;
var newDoc = app.documents[1];
var newDocName = newDoc.name;

 

Participating Frequently
February 2, 2025

Thanks for the quick reply!

I tried to recreate a file with the part that is needed. The Render output file (Beauty pass, Smart Object) with the Adjustment layers above. The first six (counting upwards) are always the same and won't be renamed. Every additional layer needs to be placed on top of the existing ones. There the script would check, if there are any additiona layers and then it would copy+paste the whole adjustment layer. This would work with my knowledge. But the first six are alerady there. (like in the files 02_Default.) Default values, but with the latest layer masks. (layer masks come from the rendering, therefore need to be up2date. Older files may have incorrect masks). But the adjustments that are made with these first six adjustment layers need to be transfered onto the new file. And there the problem starts: How? Copying the values from old to new or copy the whole adjustment layers from old to new and then update the layer mask after. Bulk or batch processing sounds fun, but I guess for now it would be sufficient if there are only pairs (old and new) open in Photoshop. Therefore the user always gets to check and confirm the process before the file gets saved. 

Ok ... so ...

 

Can you provide layered before and after PSD file examples? They don't need to be high resolution.

* Tried to create two files based on our production files, but reduced to the important part + smaller resolution.

 

What is the source of the new layer mask content? How does this differ from the original?

* Source is the Render output. New File has the correct Layer Mask. Old File has the correct values. At the these two things need to be merged. Correct values, with the correct layer mask inside the new file.

 

Do the layer names change between different files, or are they consistent?

* The default adjustment layers are consistent. There may are per-file-based layer names, but these are always on top.

 

Do you only have 2 images open at a time?

* Yes, seems to be the best workflow for overall control.

 

Are you looking for a batch solution for bulk files rather than for two open images?

* Not now, no.

 

Big thanks in advance!

 

Stephen Marsh
Community Expert
February 2, 2025

Can you provide layered before and after PSD file examples? They don't need to be high resolution.

 

What is the source of the new layer mask content? How does this differ from the original?

 

Do the layer names change between different files, or are they consistent?

 

Do you only have 2 images open at a time?

 

Are you looking for a batch solution for bulk files rather than for two open images?